diff --git a/browser/base/content/test/performance/browser_preferences_usage.js b/browser/base/content/test/performance/browser_preferences_usage.js index 1d04e27c7a60..6c7159e37557 100644 --- a/browser/base/content/test/performance/browser_preferences_usage.js +++ b/browser/base/content/test/performance/browser_preferences_usage.js @@ -89,6 +89,9 @@ add_task(async function startup() { min: 45, max: 75, }, + "network.loadinfo.skip_type_assertion": { + max: 650, + }, "extensions.getAddons.cache.enabled": { min: 9, max: 55, @@ -138,8 +141,11 @@ add_task(async function open_10_tabs() { "browser.startup.record": { max: 20, }, - "dom.max_chrome_script_run_time": { - max: 20, + "browser.tabs.remote.logSwitchTiming": { + max: 25, + }, + "network.loadinfo.skip_type_assertion": { + max: 70, }, "toolkit.cosmeticAnimations.enabled": { min: 5, @@ -170,6 +176,9 @@ add_task(async function navigate_around() { min: 100, max: 110, }, + "network.loadinfo.skip_type_assertion": { + max: 130, + }, "security.insecure_connection_icon.pbmode.enabled": { min: 20, max: 30, diff --git a/caps/BasePrincipal.cpp b/caps/BasePrincipal.cpp index 9bf1f44ee3c0..08ab4f006643 100644 --- a/caps/BasePrincipal.cpp +++ b/caps/BasePrincipal.cpp @@ -282,6 +282,13 @@ BasePrincipal::GetIsSystemPrincipal(bool* aResult) return NS_OK; } +NS_IMETHODIMP +BasePrincipal::GetIsAddonOrExpandedAddonPrincipal(bool* aResult) +{ + *aResult = AddonPolicy() || ContentScriptAddonPolicy(); + return NS_OK; +} + NS_IMETHODIMP BasePrincipal::GetOriginAttributes(JSContext* aCx, JS::MutableHandle aVal) { diff --git a/caps/BasePrincipal.h b/caps/BasePrincipal.h index 9787c19e370d..b3a6e957108a 100644 --- a/caps/BasePrincipal.h +++ b/caps/BasePrincipal.h @@ -79,6 +79,7 @@ public: NS_IMETHOD GetIsCodebasePrincipal(bool* aResult) override; NS_IMETHOD GetIsExpandedPrincipal(bool* aResult) override; NS_IMETHOD GetIsSystemPrincipal(bool* aResult) override; + NS_IMETHOD GetIsAddonOrExpandedAddonPrincipal(bool* aResult) override; NS_IMETHOD GetOriginAttributes(JSContext* aCx, JS::MutableHandle aVal) final; NS_IMETHOD GetOriginSuffix(nsACString& aOriginSuffix) final; NS_IMETHOD GetAppId(uint32_t* aAppId) final; diff --git a/caps/nsIPrincipal.idl b/caps/nsIPrincipal.idl index 7ab8f81ecf63..a1143f6aa9ff 100644 --- a/caps/nsIPrincipal.idl +++ b/caps/nsIPrincipal.idl @@ -320,6 +320,12 @@ interface nsIPrincipal : nsISerializable * Returns true iff this is the system principal. */ [infallible] readonly attribute boolean isSystemPrincipal; + + /** + * Returns true iff the principal is either an addon principal or + * an expanded principal, which contains at least one addon principal. + */ + [infallible] readonly attribute boolean isAddonOrExpandedAddonPrincipal; }; /** diff --git a/devtools/client/sourceeditor/README b/devtools/client/sourceeditor/README index 4f7f6796ab77..7c3d9cadb6c6 100644 --- a/devtools/client/sourceeditor/README +++ b/devtools/client/sourceeditor/README @@ -5,7 +5,7 @@ code, and optionally help with indentation. # Upgrade -Currently used version is 5.38.0. To upgrade: download a new version of +Currently used version is 5.39.0. To upgrade: download a new version of CodeMirror from the project's page [1] and replace all JavaScript and CSS files inside the codemirror directory [2]. diff --git a/devtools/client/sourceeditor/codemirror/codemirror.bundle.js b/devtools/client/sourceeditor/codemirror/codemirror.bundle.js index e46171bebc03..5b5baae34cbb 100644 --- a/devtools/client/sourceeditor/codemirror/codemirror.bundle.js +++ b/devtools/client/sourceeditor/codemirror/codemirror.bundle.js @@ -1 +1 @@ -var CodeMirror=function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(r,i,function(t){return e[t]}.bind(null,i));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=28)}([function(e,t,n){e.exports=function(){"use strict";var e=navigator.userAgent,t=navigator.platform,n=/gecko\/\d/i.test(e),r=/MSIE \d/.test(e),i=/Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(e),o=/Edge\/(\d+)/.exec(e),a=r||i||o,l=a&&(r?document.documentMode||6:+(o||i)[1]),s=!o&&/WebKit\//.test(e),c=s&&/Qt\/\d+\.\d+/.test(e),u=!o&&/Chrome\//.test(e),f=/Opera\//.test(e),d=/Apple Computer/.test(navigator.vendor),h=/Mac OS X 1\d\D([8-9]|\d\d)\D/.test(e),p=/PhantomJS/.test(e),m=!o&&/AppleWebKit/.test(e)&&/Mobile\/\w+/.test(e),g=/Android/.test(e),v=m||g||/webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(e),y=m||/Mac/.test(t),b=/\bCrOS\b/.test(e),x=/win/i.test(t),w=f&&e.match(/Version\/(\d*\.\d*)/);w&&(w=Number(w[1])),w&&w>=15&&(f=!1,s=!0);var k=y&&(c||f&&(null==w||w<12.11)),C=n||a&&l>=9;function S(e){return new RegExp("(^|\\s)"+e+"(?:$|\\s)\\s*")}var L,M=function(e,t){var n=e.className,r=S(t).exec(n);if(r){var i=n.slice(r.index+r[0].length);e.className=n.slice(0,r.index)+(i?r[1]+i:"")}};function T(e){for(var t=e.childNodes.length;t>0;--t)e.removeChild(e.firstChild);return e}function A(e,t){return T(e).appendChild(t)}function O(e,t,n,r){var i=document.createElement(e);if(n&&(i.className=n),r&&(i.style.cssText=r),"string"==typeof t)i.appendChild(document.createTextNode(t));else if(t)for(var o=0;o=t)return a+(t-o);a+=l-o,a+=n-a%n,o=l+1}}m?B=function(e){e.selectionStart=0,e.selectionEnd=e.value.length}:a&&(B=function(e){try{e.select()}catch(e){}});var z=function(){this.id=null};function _(e,t){for(var n=0;n=t)return r+Math.min(a,t-i);if(i+=o-r,r=o+1,(i+=n-i%n)>=t)return r}}var $=[""];function G(e){for(;$.length<=e;)$.push(X($)+" ");return $[e]}function X(e){return e[e.length-1]}function Y(e,t){for(var n=[],r=0;r"€"&&(e.toUpperCase()!=e.toLowerCase()||Q.test(e))}function te(e,t){return t?!!(t.source.indexOf("\\w")>-1&&ee(e))||t.test(e):ee(e)}function ne(e){for(var t in e)if(e.hasOwnProperty(t)&&e[t])return!1;return!0}var re=/[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/;function ie(e){return e.charCodeAt(0)>=768&&re.test(e)}function oe(e,t,n){for(;(n<0?t>0:tn?-1:1;;){if(t==n)return t;var i=(t+n)/2,o=r<0?Math.ceil(i):Math.floor(i);if(o==t)return e(o)?t:n;e(o)?n=o:t=o+r}}function le(e,t){if((t-=e.first)<0||t>=e.size)throw new Error("There is no line "+(t+e.first)+" in the document.");for(var n=e;!n.lines;)for(var r=0;;++r){var i=n.children[r],o=i.chunkSize();if(t=e.first&&tn?me(n,le(e,n).text.length):function(e,t){var n=e.ch;return null==n||n>t?me(e.line,t):n<0?me(e.line,0):e}(t,le(e,t.line).text.length)}function Ce(e,t){for(var n=[],r=0;r=t:o.to>t);(r||(r=[])).push(new Me(a,o.from,s?null:o.to))}}return r}(n,i,a),s=function(e,t,n){var r;if(e)for(var i=0;i=t:o.to>t);if(l||o.from==t&&"bookmark"==a.type&&(!n||o.marker.insertLeft)){var s=null==o.from||(a.inclusiveLeft?o.from<=t:o.from0&&l)for(var x=0;xt)&&(!n||Be(n,o.marker)<0)&&(n=o.marker)}return n}function _e(e,t,n,r,i){var o=le(e,t),a=Le&&o.markedSpans;if(a)for(var l=0;l=0&&f<=0||u<=0&&f>=0)&&(u<=0&&(s.marker.inclusiveRight&&i.inclusiveLeft?ge(c.to,n)>=0:ge(c.to,n)>0)||u>=0&&(s.marker.inclusiveRight&&i.inclusiveLeft?ge(c.from,r)<=0:ge(c.from,r)<0)))return!0}}}function He(e){for(var t;t=Fe(e);)e=t.find(-1,!0).line;return e}function Ke(e,t){var n=le(e,t),r=He(n);return n==r?t:fe(r)}function je(e,t){if(t>e.lastLine())return t;var n,r=le(e,t);if(!Ue(e,r))return t;for(;n=We(r);)r=n.find(1,!0).line;return fe(r)+1}function Ue(e,t){var n=Le&&t.markedSpans;if(n)for(var r=void 0,i=0;it.maxLineLength&&(t.maxLineLength=n,t.maxLine=e)})}var Xe=null;function Ye(e,t,n){var r;Xe=null;for(var i=0;it)return i;o.to==t&&(o.from!=o.to&&"before"==n?r=i:Xe=i),o.from==t&&(o.from!=o.to&&"before"!=n?r=i:Xe=i)}return null!=r?r:Xe}var Ze=function(){var e="bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN",t="nnnnnnNNr%%r,rNNmmmmmmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmmmnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmnNmmmmmmrrmmNmmmmrr1111111111";var n=/[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/,r=/[stwN]/,i=/[LRr]/,o=/[Lb1n]/,a=/[1n]/;function l(e,t,n){this.level=e,this.from=t,this.to=n}return function(s,c){var u,f="ltr"==c?"L":"R";if(0==s.length||"ltr"==c&&!n.test(s))return!1;for(var d=s.length,h=[],p=0;p-1&&(r[t]=i.slice(0,o).concat(i.slice(o+1)))}}}function rt(e,t){var n=tt(e,t);if(n.length)for(var r=Array.prototype.slice.call(arguments,2),i=0;i0}function lt(e){e.prototype.on=function(e,t){et(this,e,t)},e.prototype.off=function(e,t){nt(this,e,t)}}function st(e){e.preventDefault?e.preventDefault():e.returnValue=!1}function ct(e){e.stopPropagation?e.stopPropagation():e.cancelBubble=!0}function ut(e){return null!=e.defaultPrevented?e.defaultPrevented:0==e.returnValue}function ft(e){st(e),ct(e)}function dt(e){return e.target||e.srcElement}function ht(e){var t=e.which;return null==t&&(1&e.button?t=1:2&e.button?t=3:4&e.button&&(t=2)),y&&e.ctrlKey&&1==t&&(t=3),t}var pt,mt,gt=function(){if(a&&l<9)return!1;var e=O("div");return"draggable"in e||"dragDrop"in e}();function vt(e){if(null==pt){var t=O("span","​");A(e,O("span",[t,document.createTextNode("x")])),0!=e.firstChild.offsetHeight&&(pt=t.offsetWidth<=1&&t.offsetHeight>2&&!(a&&l<8))}var n=pt?O("span","​"):O("span"," ",null,"display: inline-block; width: 1px; margin-right: -1px");return n.setAttribute("cm-text",""),n}function yt(e){if(null!=mt)return mt;var t=A(e,document.createTextNode("AخA")),n=L(t,0,1).getBoundingClientRect(),r=L(t,1,2).getBoundingClientRect();return T(e),!(!n||n.left==n.right)&&(mt=r.right-n.right<3)}var bt,xt=3!="\n\nb".split(/\n/).length?function(e){for(var t=0,n=[],r=e.length;t<=r;){var i=e.indexOf("\n",t);-1==i&&(i=e.length);var o=e.slice(t,"\r"==e.charAt(i-1)?i-1:i),a=o.indexOf("\r");-1!=a?(n.push(o.slice(0,a)),t+=a+1):(n.push(o),t=i+1)}return n}:function(e){return e.split(/\r\n?|\n/)},wt=window.getSelection?function(e){try{return e.selectionStart!=e.selectionEnd}catch(e){return!1}}:function(e){var t;try{t=e.ownerDocument.selection.createRange()}catch(e){}return!(!t||t.parentElement()!=e)&&0!=t.compareEndPoints("StartToEnd",t)},kt="oncopy"in(bt=O("div"))||(bt.setAttribute("oncopy","return;"),"function"==typeof bt.oncopy),Ct=null,St={},Lt={};function Mt(e){if("string"==typeof e&&Lt.hasOwnProperty(e))e=Lt[e];else if(e&&"string"==typeof e.name&&Lt.hasOwnProperty(e.name)){var t=Lt[e.name];"string"==typeof t&&(t={name:t}),(e=J(t,e)).name=t.name}else{if("string"==typeof e&&/^[\w\-]+\/[\w\-]+\+xml$/.test(e))return Mt("application/xml");if("string"==typeof e&&/^[\w\-]+\/[\w\-]+\+json$/.test(e))return Mt("application/json")}return"string"==typeof e?{name:e}:e||{name:"null"}}function Tt(e,t){t=Mt(t);var n=St[t.name];if(!n)return Tt(e,"text/plain");var r=n(e,t);if(At.hasOwnProperty(t.name)){var i=At[t.name];for(var o in i)i.hasOwnProperty(o)&&(r.hasOwnProperty(o)&&(r["_"+o]=r[o]),r[o]=i[o])}if(r.name=t.name,t.helperType&&(r.helperType=t.helperType),t.modeProps)for(var a in t.modeProps)r[a]=t.modeProps[a];return r}var At={};function Ot(e,t){var n=At.hasOwnProperty(e)?At[e]:At[e]={};F(t,n)}function Et(e,t){if(!0===t)return t;if(e.copyState)return e.copyState(t);var n={};for(var r in t){var i=t[r];i instanceof Array&&(i=i.concat([])),n[r]=i}return n}function Nt(e,t){for(var n;e.innerMode&&(n=e.innerMode(t))&&n.mode!=e;)t=n.state,e=n.mode;return n||{mode:e,state:t}}function Pt(e,t,n){return!e.startState||e.startState(t,n)}var It=function(e,t,n){this.pos=this.start=0,this.string=e,this.tabSize=t||8,this.lastColumnPos=this.lastColumnValue=0,this.lineStart=0,this.lineOracle=n};It.prototype.eol=function(){return this.pos>=this.string.length},It.prototype.sol=function(){return this.pos==this.lineStart},It.prototype.peek=function(){return this.string.charAt(this.pos)||void 0},It.prototype.next=function(){if(this.post},It.prototype.eatSpace=function(){for(var e=this.pos;/[\s\u00a0]/.test(this.string.charAt(this.pos));)++this.pos;return this.pos>e},It.prototype.skipToEnd=function(){this.pos=this.string.length},It.prototype.skipTo=function(e){var t=this.string.indexOf(e,this.pos);if(t>-1)return this.pos=t,!0},It.prototype.backUp=function(e){this.pos-=e},It.prototype.column=function(){return this.lastColumnPos0?null:(r&&!1!==t&&(this.pos+=r[0].length),r)}var i=function(e){return n?e.toLowerCase():e},o=this.string.substr(this.pos,e.length);if(i(o)==i(e))return!1!==t&&(this.pos+=e.length),!0},It.prototype.current=function(){return this.string.slice(this.start,this.pos)},It.prototype.hideFirstChars=function(e,t){this.lineStart+=e;try{return t()}finally{this.lineStart-=e}},It.prototype.lookAhead=function(e){var t=this.lineOracle;return t&&t.lookAhead(e)},It.prototype.baseToken=function(){var e=this.lineOracle;return e&&e.baseToken(this.pos)};var Rt=function(e,t){this.state=e,this.lookAhead=t},Bt=function(e,t,n,r){this.state=t,this.doc=e,this.line=n,this.maxLookAhead=r||0,this.baseTokens=null,this.baseTokenPos=1};function Dt(e,t,n,r){var i=[e.state.modeGen],o={};Vt(e,t.text,e.doc.mode,n,function(e,t){return i.push(e,t)},o,r);for(var a=n.state,l=function(r){n.baseTokens=i;var l=e.state.overlays[r],s=1,c=0;n.state=!0,Vt(e,t.text,l.mode,n,function(e,t){for(var n=s;ce&&i.splice(s,1,e,i[s+1],r),s+=2,c=Math.min(e,r)}if(t)if(l.opaque)i.splice(n,s-n,e,"overlay "+t),s=n+2;else for(;ne.options.maxHighlightLength&&Et(e.doc.mode,r.state),o=Dt(e,t,r);i&&(r.state=i),t.stateAfter=r.save(!i),t.styles=o.styles,o.classes?t.styleClasses=o.classes:t.styleClasses&&(t.styleClasses=null),n===e.doc.highlightFrontier&&(e.doc.modeFrontier=Math.max(e.doc.modeFrontier,++e.doc.highlightFrontier))}return t.styles}function Wt(e,t,n){var r=e.doc,i=e.display;if(!r.mode.startState)return new Bt(r,!0,t);var o=function(e,t,n){for(var r,i,o=e.doc,a=n?-1:t-(e.doc.mode.innerMode?1e3:100),l=t;l>a;--l){if(l<=o.first)return o.first;var s=le(o,l-1),c=s.stateAfter;if(c&&(!n||l+(c instanceof Rt?c.lookAhead:0)<=o.modeFrontier))return l;var u=W(s.text,null,e.options.tabSize);(null==i||r>u)&&(i=l-1,r=u)}return i}(e,t,n),a=o>r.first&&le(r,o-1).stateAfter,l=a?Bt.fromSaved(r,a,o):new Bt(r,Pt(r.mode),o);return r.iter(o,t,function(n){zt(e,n.text,l);var r=l.line;n.stateAfter=r==t-1||r%5==0||r>=i.viewFrom&&rt.start)return o}throw new Error("Mode "+e.name+" failed to advance stream.")}Bt.prototype.lookAhead=function(e){var t=this.doc.getLine(this.line+e);return null!=t&&e>this.maxLookAhead&&(this.maxLookAhead=e),t},Bt.prototype.baseToken=function(e){if(!this.baseTokens)return null;for(;this.baseTokens[this.baseTokenPos]<=e;)this.baseTokenPos+=2;var t=this.baseTokens[this.baseTokenPos+1];return{type:t&&t.replace(/( |^)overlay .*/,""),size:this.baseTokens[this.baseTokenPos]-e}},Bt.prototype.nextLine=function(){this.line++,this.maxLookAhead>0&&this.maxLookAhead--},Bt.fromSaved=function(e,t,n){return t instanceof Rt?new Bt(e,Et(e.mode,t.state),n,t.lookAhead):new Bt(e,Et(e.mode,t),n)},Bt.prototype.save=function(e){var t=!1!==e?Et(this.doc.mode,this.state):this.state;return this.maxLookAhead>0?new Rt(t,this.maxLookAhead):t};var Kt=function(e,t,n){this.start=e.start,this.end=e.pos,this.string=e.current(),this.type=t||null,this.state=n};function jt(e,t,n,r){var i,o=e.doc,a=o.mode;t=ke(o,t);var l,s=le(o,t.line),c=Wt(e,t.line,n),u=new It(s.text,e.options.tabSize,c);for(r&&(l=[]);(r||u.pose.options.maxHighlightLength?(l=!1,a&&zt(e,t,r,f.pos),f.pos=t.length,s=null):s=Ut(Ht(n,f,r.state,d),o),d){var h=d[0].name;h&&(s="m-"+(s?h+" "+s:h))}if(!l||u!=s){for(;c1&&!/ /.test(e))return e;for(var n=t,r="",i=0;ic&&f.from<=c);d++);if(f.to>=u)return e(n,r,i,o,a,l,s);e(n,r.slice(0,f.to-c),i,o,null,l,s),o=null,r=r.slice(f.to-c),c=f.to}}}function tn(e,t,n,r){var i=!r&&n.widgetNode;i&&e.map.push(e.pos,e.pos+t,i),!r&&e.cm.display.input.needsContentAttribute&&(i||(i=e.content.appendChild(document.createElement("span"))),i.setAttribute("cm-marker",n.id)),i&&(e.cm.display.input.setUneditable(i),e.content.appendChild(i)),e.pos+=t,e.trailingSpace=!1}function nn(e,t,n){var r=e.markedSpans,i=e.text,o=0;if(r)for(var a,l,s,c,u,f,d,h=i.length,p=0,m=1,g="",v=0;;){if(v==p){s=c=u=f=l="",d=null,v=1/0;for(var y=[],b=void 0,x=0;xp||k.collapsed&&w.to==p&&w.from==p)?(null!=w.to&&w.to!=p&&v>w.to&&(v=w.to,c=""),k.className&&(s+=" "+k.className),k.css&&(l=(l?l+";":"")+k.css),k.startStyle&&w.from==p&&(u+=" "+k.startStyle),k.endStyle&&w.to==v&&(b||(b=[])).push(k.endStyle,w.to),k.title&&!f&&(f=k.title),k.collapsed&&(!d||Be(d.marker,k)<0)&&(d=w)):w.from>p&&v>w.from&&(v=w.from)}if(b)for(var C=0;C=h)break;for(var L=Math.min(h,v);;){if(g){var M=p+g.length;if(!d){var T=M>L?g.slice(0,L-p):g;t.addToken(t,T,a?a+s:s,u,p+T.length==v?c:"",f,l)}if(M>=L){g=g.slice(L-p),p=L;break}p=M,u=""}g=i.slice(o,o=n[m++]),a=Yt(n[m++],t.cm.options)}}else for(var A=1;An)return{map:e.measure.maps[i],cache:e.measure.caches[i],before:!0}}function En(e,t,n,r){return In(e,Pn(e,t),n,r)}function Nn(e,t){if(t>=e.display.viewFrom&&t=n.lineN&&t2&&o.push((s.bottom+c.top)/2-n.top)}}o.push(n.bottom-n.top)}}(e,t.view,t.rect),t.hasHeights=!0),(o=function(e,t,n,r){var i,o=Dn(t.map,n,r),s=o.node,c=o.start,u=o.end,f=o.collapse;if(3==s.nodeType){for(var d=0;d<4;d++){for(;c&&ie(t.line.text.charAt(o.coverStart+c));)--c;for(;o.coverStart+u1}(e))return t;var n=screen.logicalXDPI/screen.deviceXDPI,r=screen.logicalYDPI/screen.deviceYDPI;return{left:t.left*n,right:t.right*n,top:t.top*r,bottom:t.bottom*r}}(e.display.measure,i))}else{var h;c>0&&(f=r="right"),i=e.options.lineWrapping&&(h=s.getClientRects()).length>1?h["right"==r?h.length-1:0]:s.getBoundingClientRect()}if(a&&l<9&&!c&&(!i||!i.left&&!i.right)){var p=s.parentNode.getClientRects()[0];i=p?{left:p.left,right:p.left+nr(e.display),top:p.top,bottom:p.bottom}:Bn}for(var m=i.top-t.rect.top,g=i.bottom-t.rect.top,v=(m+g)/2,y=t.view.measure.heights,b=0;bt)&&(i=(o=s-l)-1,t>=s&&(a="right")),null!=i){if(r=e[c+2],l==s&&n==(r.insertLeft?"left":"right")&&(a=n),"left"==n&&0==i)for(;c&&e[c-2]==e[c-3]&&e[c-1].insertLeft;)r=e[2+(c-=3)],a="left";if("right"==n&&i==s-l)for(;c=0&&(n=e[i]).left==n.right;i--);return n}function Wn(e){if(e.measure&&(e.measure.cache={},e.measure.heights=null,e.rest))for(var t=0;t=r.text.length?(s=r.text.length,c="before"):s<=0&&(s=0,c="after"),!l)return a("before"==c?s-1:s,"before"==c);function u(e,t,n){var r=l[t],i=1==r.level;return a(n?e-1:e,i!=n)}var f=Ye(l,s,c),d=Xe,h=u(s,f,"before"==c);return null!=d&&(h.other=u(s,d,"before"!=c)),h}function Gn(e,t){var n=0;t=ke(e.doc,t),e.options.lineWrapping||(n=nr(e.display)*t.ch);var r=le(e.doc,t.line),i=qe(r)+Cn(e.display);return{left:n,right:n,top:i,bottom:i+r.height}}function Xn(e,t,n,r,i){var o=me(e,t,n);return o.xRel=i,r&&(o.outside=!0),o}function Yn(e,t,n){var r=e.doc;if((n+=e.display.viewOffset)<0)return Xn(r.first,0,null,!0,-1);var i=de(r,n),o=r.first+r.size-1;if(i>o)return Xn(r.first+r.size-1,le(r,o).text.length,null,!0,1);t<0&&(t=0);for(var a=le(r,i);;){var l=er(e,a,i,t,n),s=ze(a,l.ch+(l.xRel>0?1:0));if(!s)return l;var c=s.find(1);if(c.line==i)return c;a=le(r,i=c.line)}}function Zn(e,t,n,r){r-=jn(t);var i=t.text.length,o=ae(function(t){return In(e,n,t-1).bottom<=r},i,0);return i=ae(function(t){return In(e,n,t).top>r},o,i),{begin:o,end:i}}function Jn(e,t,n,r){n||(n=Pn(e,t));var i=Un(e,t,In(e,n,r),"line").top;return Zn(e,t,n,i)}function Qn(e,t,n,r){return!(e.bottom<=n)&&(e.top>n||(r?e.left:e.right)>t)}function er(e,t,n,r,i){i-=qe(t);var o=Pn(e,t),a=jn(t),l=0,s=t.text.length,c=!0,u=Je(t,e.doc.direction);if(u){var f=(e.options.lineWrapping?function(e,t,n,r,i,o,a){var l=Zn(e,t,r,a),s=l.begin,c=l.end;/\s/.test(t.text.charAt(c-1))&&c--;for(var u=null,f=null,d=0;d=c||h.to<=s)){var p=1!=h.level,m=In(e,r,p?Math.min(c,h.to)-1:Math.max(s,h.from)).right,g=mg)&&(u=h,f=g)}}return u||(u=i[i.length-1]),u.fromc&&(u={from:u.from,to:c,level:u.level}),u}:function(e,t,n,r,i,o,a){var l=ae(function(l){var s=i[l],c=1!=s.level;return Qn($n(e,me(n,c?s.to:s.from,c?"before":"after"),"line",t,r),o,a,!0)},0,i.length-1),s=i[l];if(l>0){var c=1!=s.level,u=$n(e,me(n,c?s.from:s.to,c?"after":"before"),"line",t,r);Qn(u,o,a,!0)&&u.top>a&&(s=i[l-1])}return s})(e,t,n,o,u,r,i);c=1!=f.level,l=c?f.from:f.to-1,s=c?f.to:f.from-1}var d,h,p=null,m=null,g=ae(function(t){var n=In(e,o,t);return n.top+=a,n.bottom+=a,!!Qn(n,r,i,!1)&&(n.top<=i&&n.left<=r&&(p=t,m=n),!0)},l,s),v=!1;if(m){var y=r-m.left=x.bottom}return g=oe(t.text,g,1),Xn(n,g,h,v,r-d)}function tr(e){if(null!=e.cachedTextHeight)return e.cachedTextHeight;if(null==Rn){Rn=O("pre");for(var t=0;t<49;++t)Rn.appendChild(document.createTextNode("x")),Rn.appendChild(O("br"));Rn.appendChild(document.createTextNode("x"))}A(e.measure,Rn);var n=Rn.offsetHeight/50;return n>3&&(e.cachedTextHeight=n),T(e.measure),n||1}function nr(e){if(null!=e.cachedCharWidth)return e.cachedCharWidth;var t=O("span","xxxxxxxxxx"),n=O("pre",[t]);A(e.measure,n);var r=t.getBoundingClientRect(),i=(r.right-r.left)/10;return i>2&&(e.cachedCharWidth=i),i||10}function rr(e){for(var t=e.display,n={},r={},i=t.gutters.clientLeft,o=t.gutters.firstChild,a=0;o;o=o.nextSibling,++a)n[e.options.gutters[a]]=o.offsetLeft+o.clientLeft+i,r[e.options.gutters[a]]=o.clientWidth;return{fixedPos:ir(t),gutterTotalWidth:t.gutters.offsetWidth,gutterLeft:n,gutterWidth:r,wrapperWidth:t.wrapper.clientWidth}}function ir(e){return e.scroller.getBoundingClientRect().left-e.sizer.getBoundingClientRect().left}function or(e){var t=tr(e.display),n=e.options.lineWrapping,r=n&&Math.max(5,e.display.scroller.clientWidth/nr(e.display)-3);return function(i){if(Ue(e.doc,i))return 0;var o=0;if(i.widgets)for(var a=0;a=e.display.viewTo)return null;if((t-=e.display.viewFrom)<0)return null;for(var n=e.display.view,r=0;r=e.display.viewTo||l.to().linet||t==n&&a.to==t)&&(r(Math.max(a.from,t),Math.min(a.to,n),1==a.level?"rtl":"ltr",o),i=!0)}i||r(t,n,"ltr")}(m,n||0,null==r?d:r,function(e,t,i,f){var g="ltr"==i,v=h(e,g?"left":"right"),y=h(t-1,g?"right":"left"),b=null==n&&0==e,x=null==r&&t==d,w=0==f,k=!m||f==m.length-1;if(y.top-v.top<=3){var C=(c?b:x)&&w,S=(c?x:b)&&k,L=C?l:(g?v:y).left,M=S?s:(g?y:v).right;u(L,v.top,M-L,v.bottom)}else{var T,A,O,E;g?(T=c&&b&&w?l:v.left,A=c?s:p(e,i,"before"),O=c?l:p(t,i,"after"),E=c&&x&&k?s:y.right):(T=c?p(e,i,"before"):l,A=!c&&b&&w?s:v.right,O=!c&&x&&k?l:y.left,E=c?p(t,i,"after"):s),u(T,v.top,A-T,v.bottom),v.bottom0?t.blinker=setInterval(function(){return t.cursorDiv.style.visibility=(n=!n)?"":"hidden"},e.options.cursorBlinkRate):e.options.cursorBlinkRate<0&&(t.cursorDiv.style.visibility="hidden")}}function mr(e){e.state.focused||(e.display.input.focus(),vr(e))}function gr(e){e.state.delayingBlurEvent=!0,setTimeout(function(){e.state.delayingBlurEvent&&(e.state.delayingBlurEvent=!1,yr(e))},100)}function vr(e,t){e.state.delayingBlurEvent&&(e.state.delayingBlurEvent=!1),"nocursor"!=e.options.readOnly&&(e.state.focused||(rt(e,"focus",e,t),e.state.focused=!0,I(e.display.wrapper,"CodeMirror-focused"),e.curOp||e.display.selForContextMenu==e.doc.sel||(e.display.input.reset(),s&&setTimeout(function(){return e.display.input.reset(!0)},20)),e.display.input.receivedFocus()),pr(e))}function yr(e,t){e.state.delayingBlurEvent||(e.state.focused&&(rt(e,"blur",e,t),e.state.focused=!1,M(e.display.wrapper,"CodeMirror-focused")),clearInterval(e.display.blinker),setTimeout(function(){e.state.focused||(e.display.shift=!1)},150))}function br(e){for(var t=e.display,n=t.lineDiv.offsetTop,r=0;r.005||u<-.005)&&(ue(i.line,o),xr(i.line),i.rest))for(var f=0;f=a&&(o=de(t,qe(le(t,s))-e.wrapper.clientHeight),a=s)}return{from:o,to:Math.max(a,o+1)}}function kr(e){var t=e.display,n=t.view;if(t.alignWidgets||t.gutters.firstChild&&e.options.fixedGutter){for(var r=ir(t)-t.scroller.scrollLeft+e.doc.scrollLeft,i=t.gutters.offsetWidth,o=r+"px",a=0;ao&&(t.bottom=t.top+o);var l=e.doc.height+Sn(n),s=t.topl-r;if(t.topi+o){var u=Math.min(t.top,(c?l:t.bottom)-o);u!=i&&(a.scrollTop=u)}var f=e.curOp&&null!=e.curOp.scrollLeft?e.curOp.scrollLeft:n.scroller.scrollLeft,d=Tn(e)-(e.options.fixedGutter?n.gutters.offsetWidth:0),h=t.right-t.left>d;return h&&(t.right=t.left+d),t.left<10?a.scrollLeft=0:t.leftd+f-3&&(a.scrollLeft=t.right+(h?0:10)-d),a}function Lr(e,t){null!=t&&(Ar(e),e.curOp.scrollTop=(null==e.curOp.scrollTop?e.doc.scrollTop:e.curOp.scrollTop)+t)}function Mr(e){Ar(e);var t=e.getCursor();e.curOp.scrollToPos={from:t,to:t,margin:e.options.cursorScrollMargin}}function Tr(e,t,n){null==t&&null==n||Ar(e),null!=t&&(e.curOp.scrollLeft=t),null!=n&&(e.curOp.scrollTop=n)}function Ar(e){var t=e.curOp.scrollToPos;if(t){e.curOp.scrollToPos=null;var n=Gn(e,t.from),r=Gn(e,t.to);Or(e,n,r,t.margin)}}function Or(e,t,n,r){var i=Sr(e,{left:Math.min(t.left,n.left),top:Math.min(t.top,n.top)-r,right:Math.max(t.right,n.right),bottom:Math.max(t.bottom,n.bottom)+r});Tr(e,i.scrollLeft,i.scrollTop)}function Er(e,t){Math.abs(e.doc.scrollTop-t)<2||(n||li(e,{top:t}),Nr(e,t,!0),n&&li(e),ni(e,100))}function Nr(e,t,n){t=Math.min(e.display.scroller.scrollHeight-e.display.scroller.clientHeight,t),(e.display.scroller.scrollTop!=t||n)&&(e.doc.scrollTop=t,e.display.scrollbars.setScrollTop(t),e.display.scroller.scrollTop!=t&&(e.display.scroller.scrollTop=t))}function Pr(e,t,n,r){t=Math.min(t,e.display.scroller.scrollWidth-e.display.scroller.clientWidth),(n?t==e.doc.scrollLeft:Math.abs(e.doc.scrollLeft-t)<2)&&!r||(e.doc.scrollLeft=t,kr(e),e.display.scroller.scrollLeft!=t&&(e.display.scroller.scrollLeft=t),e.display.scrollbars.setScrollLeft(t))}function Ir(e){var t=e.display,n=t.gutters.offsetWidth,r=Math.round(e.doc.height+Sn(e.display));return{clientHeight:t.scroller.clientHeight,viewHeight:t.wrapper.clientHeight,scrollWidth:t.scroller.scrollWidth,clientWidth:t.scroller.clientWidth,viewWidth:t.wrapper.clientWidth,barLeft:e.options.fixedGutter?n:0,docHeight:r,scrollHeight:r+Mn(e)+t.barHeight,nativeBarWidth:t.nativeBarWidth,gutterWidth:n}}var Rr=function(e,t,n){this.cm=n;var r=this.vert=O("div",[O("div",null,null,"min-width: 1px")],"CodeMirror-vscrollbar"),i=this.horiz=O("div",[O("div",null,null,"height: 100%; min-height: 1px")],"CodeMirror-hscrollbar");r.tabIndex=i.tabIndex=-1,e(r),e(i),et(r,"scroll",function(){r.clientHeight&&t(r.scrollTop,"vertical")}),et(i,"scroll",function(){i.clientWidth&&t(i.scrollLeft,"horizontal")}),this.checkedZeroWidth=!1,a&&l<8&&(this.horiz.style.minHeight=this.vert.style.minWidth="18px")};Rr.prototype.update=function(e){var t=e.scrollWidth>e.clientWidth+1,n=e.scrollHeight>e.clientHeight+1,r=e.nativeBarWidth;if(n){this.vert.style.display="block",this.vert.style.bottom=t?r+"px":"0";var i=e.viewHeight-(t?r:0);this.vert.firstChild.style.height=Math.max(0,e.scrollHeight-e.clientHeight+i)+"px"}else this.vert.style.display="",this.vert.firstChild.style.height="0";if(t){this.horiz.style.display="block",this.horiz.style.right=n?r+"px":"0",this.horiz.style.left=e.barLeft+"px";var o=e.viewWidth-e.barLeft-(n?r:0);this.horiz.firstChild.style.width=Math.max(0,e.scrollWidth-e.clientWidth+o)+"px"}else this.horiz.style.display="",this.horiz.firstChild.style.width="0";return!this.checkedZeroWidth&&e.clientHeight>0&&(0==r&&this.zeroWidthHack(),this.checkedZeroWidth=!0),{right:n?r:0,bottom:t?r:0}},Rr.prototype.setScrollLeft=function(e){this.horiz.scrollLeft!=e&&(this.horiz.scrollLeft=e),this.disableHoriz&&this.enableZeroWidthBar(this.horiz,this.disableHoriz,"horiz")},Rr.prototype.setScrollTop=function(e){this.vert.scrollTop!=e&&(this.vert.scrollTop=e),this.disableVert&&this.enableZeroWidthBar(this.vert,this.disableVert,"vert")},Rr.prototype.zeroWidthHack=function(){var e=y&&!h?"12px":"18px";this.horiz.style.height=this.vert.style.width=e,this.horiz.style.pointerEvents=this.vert.style.pointerEvents="none",this.disableHoriz=new z,this.disableVert=new z},Rr.prototype.enableZeroWidthBar=function(e,t,n){e.style.pointerEvents="auto",t.set(1e3,function r(){var i=e.getBoundingClientRect(),o="vert"==n?document.elementFromPoint(i.right-1,(i.top+i.bottom)/2):document.elementFromPoint((i.right+i.left)/2,i.bottom-1);o!=e?e.style.pointerEvents="none":t.set(1e3,r)})},Rr.prototype.clear=function(){var e=this.horiz.parentNode;e.removeChild(this.horiz),e.removeChild(this.vert)};var Br=function(){};function Dr(e,t){t||(t=Ir(e));var n=e.display.barWidth,r=e.display.barHeight;Fr(e,t);for(var i=0;i<4&&n!=e.display.barWidth||r!=e.display.barHeight;i++)n!=e.display.barWidth&&e.options.lineWrapping&&br(e),Fr(e,Ir(e)),n=e.display.barWidth,r=e.display.barHeight}function Fr(e,t){var n=e.display,r=n.scrollbars.update(t);n.sizer.style.paddingRight=(n.barWidth=r.right)+"px",n.sizer.style.paddingBottom=(n.barHeight=r.bottom)+"px",n.heightForcer.style.borderBottom=r.bottom+"px solid transparent",r.right&&r.bottom?(n.scrollbarFiller.style.display="block",n.scrollbarFiller.style.height=r.bottom+"px",n.scrollbarFiller.style.width=r.right+"px"):n.scrollbarFiller.style.display="",r.bottom&&e.options.coverGutterNextToScrollbar&&e.options.fixedGutter?(n.gutterFiller.style.display="block",n.gutterFiller.style.height=r.bottom+"px",n.gutterFiller.style.width=t.gutterWidth+"px"):n.gutterFiller.style.display=""}Br.prototype.update=function(){return{bottom:0,right:0}},Br.prototype.setScrollLeft=function(){},Br.prototype.setScrollTop=function(){},Br.prototype.clear=function(){};var Wr={native:Rr,null:Br};function zr(e){e.display.scrollbars&&(e.display.scrollbars.clear(),e.display.scrollbars.addClass&&M(e.display.wrapper,e.display.scrollbars.addClass)),e.display.scrollbars=new Wr[e.options.scrollbarStyle](function(t){e.display.wrapper.insertBefore(t,e.display.scrollbarFiller),et(t,"mousedown",function(){e.state.focused&&setTimeout(function(){return e.display.input.focus()},0)}),t.setAttribute("cm-not-content","true")},function(t,n){"horizontal"==n?Pr(e,t):Er(e,t)},e),e.display.scrollbars.addClass&&I(e.display.wrapper,e.display.scrollbars.addClass)}var _r=0;function Hr(e){var t;e.curOp={cm:e,viewChanged:!1,startHeight:e.doc.height,forceUpdate:!1,updateInput:null,typing:!1,changeObjs:null,cursorActivityHandlers:null,cursorActivityCalled:0,selectionChanged:!1,updateMaxLine:!1,scrollLeft:null,scrollTop:null,scrollToPos:null,focus:!1,id:++_r},t=e.curOp,an?an.ops.push(t):t.ownsGroup=an={ops:[t],delayedCallbacks:[]}}function Kr(e){var t=e.curOp;!function(e,t){var n=e.ownsGroup;if(n)try{!function(e){var t=e.delayedCallbacks,n=0;do{for(;n=n.viewTo)||n.maxLineChanged&&t.options.lineWrapping,e.update=e.mustUpdate&&new ii(t,e.mustUpdate&&{top:e.scrollTop,ensure:e.scrollToPos},e.forceUpdate)}function Ur(e){var t=e.cm,n=t.display;e.updatedDisplay&&br(t),e.barMeasure=Ir(t),n.maxLineChanged&&!t.options.lineWrapping&&(e.adjustWidthTo=En(t,n.maxLine,n.maxLine.text.length).left+3,t.display.sizerWidth=e.adjustWidthTo,e.barMeasure.scrollWidth=Math.max(n.scroller.clientWidth,n.sizer.offsetLeft+e.adjustWidthTo+Mn(t)+t.display.barWidth),e.maxScrollLeft=Math.max(0,n.sizer.offsetLeft+e.adjustWidthTo-Tn(t))),(e.updatedDisplay||e.selectionChanged)&&(e.preparedSelection=n.input.prepareSelection())}function Vr(e){var t=e.cm;null!=e.adjustWidthTo&&(t.display.sizer.style.minWidth=e.adjustWidthTo+"px",e.maxScrollLeft1&&(a=!0)),null!=c.scrollLeft&&(Pr(e,c.scrollLeft),Math.abs(e.doc.scrollLeft-f)>1&&(a=!0)),!a)break}return i}(t,ke(r,e.scrollToPos.from),ke(r,e.scrollToPos.to),e.scrollToPos.margin);!function(e,t){if(!it(e,"scrollCursorIntoView")){var n=e.display,r=n.sizer.getBoundingClientRect(),i=null;if(t.top+r.top<0?i=!0:t.bottom+r.top>(window.innerHeight||document.documentElement.clientHeight)&&(i=!1),null!=i&&!p){var o=O("div","​",null,"position: absolute;\n top: "+(t.top-n.viewOffset-Cn(e.display))+"px;\n height: "+(t.bottom-t.top+Mn(e)+n.barHeight)+"px;\n left: "+t.left+"px; width: "+Math.max(2,t.right-t.left)+"px;");e.display.lineSpace.appendChild(o),o.scrollIntoView(i),e.display.lineSpace.removeChild(o)}}}(t,i)}var o=e.maybeHiddenMarkers,a=e.maybeUnhiddenMarkers;if(o)for(var l=0;lt)&&(i.updateLineNumbers=t),e.curOp.viewChanged=!0,t>=i.viewTo)Le&&Ke(e.doc,t)i.viewFrom?Qr(e):(i.viewFrom+=r,i.viewTo+=r);else if(t<=i.viewFrom&&n>=i.viewTo)Qr(e);else if(t<=i.viewFrom){var o=ei(e,n,n+r,1);o?(i.view=i.view.slice(o.index),i.viewFrom=o.lineN,i.viewTo+=r):Qr(e)}else if(n>=i.viewTo){var a=ei(e,t,t,-1);a?(i.view=i.view.slice(0,a.index),i.viewTo=a.lineN):Qr(e)}else{var l=ei(e,t,t,-1),s=ei(e,n,n+r,1);l&&s?(i.view=i.view.slice(0,l.index).concat(on(e,l.lineN,s.lineN)).concat(i.view.slice(s.index)),i.viewTo+=r):Qr(e)}var c=i.externalMeasured;c&&(n=i.lineN&&t=r.viewTo)){var o=r.view[sr(e,t)];if(null!=o.node){var a=o.changes||(o.changes=[]);-1==_(a,n)&&a.push(n)}}}function Qr(e){e.display.viewFrom=e.display.viewTo=e.doc.first,e.display.view=[],e.display.viewOffset=0}function ei(e,t,n,r){var i,o=sr(e,t),a=e.display.view;if(!Le||n==e.doc.first+e.doc.size)return{index:o,lineN:n};for(var l=e.display.viewFrom,s=0;s0){if(o==a.length-1)return null;i=l+a[o].size-t,o++}else i=l-t;t+=i,n+=i}for(;Ke(e.doc,n)!=n;){if(o==(r<0?0:a.length-1))return null;n+=r*a[o-(r<0?1:0)].size,o+=r}return{index:o,lineN:n}}function ti(e){for(var t=e.display.view,n=0,r=0;r=e.display.viewTo)){var n=+new Date+e.options.workTime,r=Wt(e,t.highlightFrontier),i=[];t.iter(r.line,Math.min(t.first+t.size,e.display.viewTo+500),function(o){if(r.line>=e.display.viewFrom){var a=o.styles,l=o.text.length>e.options.maxHighlightLength?Et(t.mode,r.state):null,s=Dt(e,o,r,!0);l&&(r.state=l),o.styles=s.styles;var c=o.styleClasses,u=s.classes;u?o.styleClasses=u:c&&(o.styleClasses=null);for(var f=!a||a.length!=o.styles.length||c!=u&&(!c||!u||c.bgClass!=u.bgClass||c.textClass!=u.textClass),d=0;!f&&dn)return ni(e,e.options.workDelay),!0}),t.highlightFrontier=r.line,t.modeFrontier=Math.max(t.modeFrontier,r.line),i.length&&$r(e,function(){for(var t=0;t=n.viewFrom&&t.visible.to<=n.viewTo&&(null==n.updateLineNumbers||n.updateLineNumbers>=n.viewTo)&&n.renderedView==n.view&&0==ti(e))return!1;Cr(e)&&(Qr(e),t.dims=rr(e));var i=r.first+r.size,o=Math.max(t.visible.from-e.options.viewportMargin,r.first),a=Math.min(i,t.visible.to+e.options.viewportMargin);n.viewFroma&&n.viewTo-a<20&&(a=Math.min(i,n.viewTo)),Le&&(o=Ke(e.doc,o),a=je(e.doc,a));var l=o!=n.viewFrom||a!=n.viewTo||n.lastWrapHeight!=t.wrapperHeight||n.lastWrapWidth!=t.wrapperWidth;!function(e,t,n){var r=e.display;0==r.view.length||t>=r.viewTo||n<=r.viewFrom?(r.view=on(e,t,n),r.viewFrom=t):(r.viewFrom>t?r.view=on(e,t,r.viewFrom).concat(r.view):r.viewFromn&&(r.view=r.view.slice(0,sr(e,n)))),r.viewTo=n}(e,o,a),n.viewOffset=qe(le(e.doc,n.viewFrom)),e.display.mover.style.top=n.viewOffset+"px";var c=ti(e);if(!l&&0==c&&!t.force&&n.renderedView==n.view&&(null==n.updateLineNumbers||n.updateLineNumbers>=n.viewTo))return!1;var u=function(e){if(e.hasFocus())return null;var t=P();if(!t||!N(e.display.lineDiv,t))return null;var n={activeElt:t};if(window.getSelection){var r=window.getSelection();r.anchorNode&&r.extend&&N(e.display.lineDiv,r.anchorNode)&&(n.anchorNode=r.anchorNode,n.anchorOffset=r.anchorOffset,n.focusNode=r.focusNode,n.focusOffset=r.focusOffset)}return n}(e);return c>4&&(n.lineDiv.style.display="none"),function(e,t,n){var r=e.display,i=e.options.lineNumbers,o=r.lineDiv,a=o.firstChild;function l(t){var n=t.nextSibling;return s&&y&&e.display.currentWheelTarget==t?t.style.display="none":t.parentNode.removeChild(t),n}for(var c=r.view,u=r.viewFrom,f=0;f-1&&(h=!1),un(e,d,u,n)),h&&(T(d.lineNumber),d.lineNumber.appendChild(document.createTextNode(pe(e.options,u)))),a=d.node.nextSibling}else{var p=vn(e,d,u,n);o.insertBefore(p,a)}u+=d.size}for(;a;)a=l(a)}(e,n.updateLineNumbers,t.dims),c>4&&(n.lineDiv.style.display=""),n.renderedView=n.view,function(e){if(e&&e.activeElt&&e.activeElt!=P()&&(e.activeElt.focus(),e.anchorNode&&N(document.body,e.anchorNode)&&N(document.body,e.focusNode))){var t=window.getSelection(),n=document.createRange();n.setEnd(e.anchorNode,e.anchorOffset),n.collapse(!1),t.removeAllRanges(),t.addRange(n),t.extend(e.focusNode,e.focusOffset)}}(u),T(n.cursorDiv),T(n.selectionDiv),n.gutters.style.height=n.sizer.style.minHeight=0,l&&(n.lastWrapHeight=t.wrapperHeight,n.lastWrapWidth=t.wrapperWidth,ni(e,400)),n.updateLineNumbers=null,!0}function ai(e,t){for(var n=t.viewport,r=!0;(r&&e.options.lineWrapping&&t.oldDisplayWidth!=Tn(e)||(n&&null!=n.top&&(n={top:Math.min(e.doc.height+Sn(e.display)-An(e),n.top)}),t.visible=wr(e.display,e.doc,n),!(t.visible.from>=e.display.viewFrom&&t.visible.to<=e.display.viewTo)))&&oi(e,t);r=!1){br(e);var i=Ir(e);cr(e),Dr(e,i),ci(e,i),t.force=!1}t.signal(e,"update",e),e.display.viewFrom==e.display.reportedViewFrom&&e.display.viewTo==e.display.reportedViewTo||(t.signal(e,"viewportChange",e,e.display.viewFrom,e.display.viewTo),e.display.reportedViewFrom=e.display.viewFrom,e.display.reportedViewTo=e.display.viewTo)}function li(e,t){var n=new ii(e,t);if(oi(e,n)){br(e),ai(e,n);var r=Ir(e);cr(e),Dr(e,r),ci(e,r),n.finish()}}function si(e){var t=e.display.gutters.offsetWidth;e.display.sizer.style.marginLeft=t+"px"}function ci(e,t){e.display.sizer.style.minHeight=t.docHeight+"px",e.display.heightForcer.style.top=t.docHeight+"px",e.display.gutters.style.height=t.docHeight+e.display.barHeight+Mn(e)+"px"}function ui(e){var t=e.display.gutters,n=e.options.gutters;T(t);for(var r=0;r-1&&!e.lineNumbers&&(e.gutters=e.gutters.slice(0),e.gutters.splice(t,1))}ii.prototype.signal=function(e,t){at(e,t)&&this.events.push(arguments)},ii.prototype.finish=function(){for(var e=0;el.clientWidth,u=l.scrollHeight>l.clientHeight;if(i&&c||o&&u){if(o&&y&&s)e:for(var d=t.target,h=a.view;d!=l;d=d.parentNode)for(var p=0;p=0&&ge(e,r.to())<=0)return n}return-1};var yi=function(e,t){this.anchor=e,this.head=t};function bi(e,t){var n=e[t];e.sort(function(e,t){return ge(e.from(),t.from())}),t=_(e,n);for(var r=1;r=0){var a=xe(o.from(),i.from()),l=be(o.to(),i.to()),s=o.empty()?i.from()==i.head:o.from()==o.head;r<=t&&--t,e.splice(--r,2,new yi(s?l:a,s?a:l))}}return new vi(e,t)}function xi(e,t){return new vi([new yi(e,t||e)],0)}function wi(e){return e.text?me(e.from.line+e.text.length-1,X(e.text).length+(1==e.text.length?e.from.ch:0)):e.to}function ki(e,t){if(ge(e,t.from)<0)return e;if(ge(e,t.to)<=0)return wi(t);var n=e.line+t.text.length-(t.to.line-t.from.line)-1,r=e.ch;return e.line==t.to.line&&(r+=wi(t).ch-t.to.ch),me(n,r)}function Ci(e,t){for(var n=[],r=0;r1&&e.remove(l.line+1,p-1),e.insert(l.line+1,v)}sn(e,"change",e,t)}function Oi(e,t,n){!function e(r,i,o){if(r.linked)for(var a=0;al-(e.cm?e.cm.options.historyEventDelay:500)||"*"==t.origin.charAt(0)))&&(o=function(e,t){return t?(Ri(e.done),X(e.done)):e.done.length&&!X(e.done).ranges?X(e.done):e.done.length>1&&!e.done[e.done.length-2].ranges?(e.done.pop(),X(e.done)):void 0}(i,i.lastOp==r)))a=X(o.changes),0==ge(t.from,t.to)&&0==ge(t.from,a.to)?a.to=wi(t):o.changes.push(Ii(e,t));else{var s=X(i.done);for(s&&s.ranges||Fi(e.sel,i.done),o={changes:[Ii(e,t)],generation:i.generation},i.done.push(o);i.done.length>i.undoDepth;)i.done.shift(),i.done[0].ranges||i.done.shift()}i.done.push(n),i.generation=++i.maxGeneration,i.lastModTime=i.lastSelTime=l,i.lastOp=i.lastSelOp=r,i.lastOrigin=i.lastSelOrigin=t.origin,a||rt(e,"historyAdded")}function Di(e,t,n,r){var i=e.history,o=r&&r.origin;n==i.lastSelOp||o&&i.lastSelOrigin==o&&(i.lastModTime==i.lastSelTime&&i.lastOrigin==o||function(e,t,n,r){var i=t.charAt(0);return"*"==i||"+"==i&&n.ranges.length==r.ranges.length&&n.somethingSelected()==r.somethingSelected()&&new Date-e.history.lastSelTime<=(e.cm?e.cm.options.historyEventDelay:500)}(e,o,X(i.done),t))?i.done[i.done.length-1]=t:Fi(t,i.done),i.lastSelTime=+new Date,i.lastSelOrigin=o,i.lastSelOp=n,r&&!1!==r.clearRedo&&Ri(i.undone)}function Fi(e,t){var n=X(t);n&&n.ranges&&n.equals(e)||t.push(e)}function Wi(e,t,n,r){var i=t["spans_"+e.id],o=0;e.iter(Math.max(e.first,n),Math.min(e.first+e.size,r),function(n){n.markedSpans&&((i||(i=t["spans_"+e.id]={}))[o]=n.markedSpans),++o})}function zi(e){if(!e)return null;for(var t,n=0;n-1&&(X(l)[f]=c[f],delete c[f])}}}return r}function Ki(e,t,n,r){if(r){var i=e.anchor;if(n){var o=ge(t,i)<0;o!=ge(n,i)<0?(i=t,t=n):o!=ge(t,n)<0&&(t=n)}return new yi(i,t)}return new yi(n||t,t)}function ji(e,t,n,r,i){null==i&&(i=e.cm&&(e.cm.display.shift||e.extend)),Gi(e,new vi([Ki(e.sel.primary(),t,n,i)],0),r)}function Ui(e,t,n){for(var r=[],i=e.cm&&(e.cm.display.shift||e.extend),o=0;o=t.ch:l.to>t.ch))){if(i&&(rt(s,"beforeCursorEnter"),s.explicitlyCleared)){if(o.markedSpans){--a;continue}break}if(!s.atomic)continue;if(n){var c=s.find(r<0?1:-1),u=void 0;if((r<0?s.inclusiveRight:s.inclusiveLeft)&&(c=to(e,c,-r,c&&c.line==t.line?o:null)),c&&c.line==t.line&&(u=ge(c,n))&&(r<0?u<0:u>0))return Qi(e,c,t,r,i)}var f=s.find(r<0?-1:1);return(r<0?s.inclusiveLeft:s.inclusiveRight)&&(f=to(e,f,r,f.line==t.line?o:null)),f?Qi(e,f,t,r,i):null}}return t}function eo(e,t,n,r,i){var o=r||1,a=Qi(e,t,n,o,i)||!i&&Qi(e,t,n,o,!0)||Qi(e,t,n,-o,i)||!i&&Qi(e,t,n,-o,!0);return a||(e.cantEdit=!0,me(e.first,0))}function to(e,t,n,r){return n<0&&0==t.ch?t.line>e.first?ke(e,me(t.line-1)):null:n>0&&t.ch==(r||le(e,t.line)).text.length?t.line0)){var u=[s,1],f=ge(c.from,l.from),d=ge(c.to,l.to);(f<0||!a.inclusiveLeft&&!f)&&u.push({from:c.from,to:l.from}),(d>0||!a.inclusiveRight&&!d)&&u.push({from:l.to,to:c.to}),i.splice.apply(i,u),s+=u.length-3}}return i}(e,t.from,t.to);if(r)for(var i=r.length-1;i>=0;--i)oo(e,{from:r[i].from,to:r[i].to,text:i?[""]:t.text,origin:t.origin});else oo(e,t)}}function oo(e,t){if(1!=t.text.length||""!=t.text[0]||0!=ge(t.from,t.to)){var n=Ci(e,t);Bi(e,t,n,e.cm?e.cm.curOp.id:NaN),so(e,t,n,Oe(e,t));var r=[];Oi(e,function(e,n){n||-1!=_(r,e.history)||(ho(e.history,t),r.push(e.history)),so(e,t,null,Oe(e,t))})}}function ao(e,t,n){var r=e.cm&&e.cm.state.suppressEdits;if(!r||n){for(var i,o=e.history,a=e.sel,l="undo"==t?o.done:o.undone,s="undo"==t?o.undone:o.done,c=0;c=0;--h){var p=d(h);if(p)return p.v}}}}function lo(e,t){if(0!=t&&(e.first+=t,e.sel=new vi(Y(e.sel.ranges,function(e){return new yi(me(e.anchor.line+t,e.anchor.ch),me(e.head.line+t,e.head.ch))}),e.sel.primIndex),e.cm)){Zr(e.cm,e.first,e.first-t,t);for(var n=e.cm.display,r=n.viewFrom;re.lastLine())){if(t.from.lineo&&(t={from:t.from,to:me(o,le(e,o).text.length),text:[t.text[0]],origin:t.origin}),t.removed=se(e,t.from,t.to),n||(n=Ci(e,t)),e.cm?function(e,t,n){var r=e.doc,i=e.display,o=t.from,a=t.to,l=!1,s=o.line;e.options.lineWrapping||(s=fe(He(le(r,o.line))),r.iter(s,a.line+1,function(e){if(e==i.maxLine)return l=!0,!0})),r.sel.contains(t.from,t.to)>-1&&ot(e),Ai(r,t,n,or(e)),e.options.lineWrapping||(r.iter(s,o.line+t.text.length,function(e){var t=$e(e);t>i.maxLineLength&&(i.maxLine=e,i.maxLineLength=t,i.maxLineChanged=!0,l=!1)}),l&&(e.curOp.updateMaxLine=!0)),function(e,t){if(e.modeFrontier=Math.min(e.modeFrontier,t),!(e.highlightFrontiern;r--){var i=le(e,r).stateAfter;if(i&&(!(i instanceof Rt)||r+i.lookAhead1||!(this.children[0]instanceof mo))){var l=[];this.collapse(l),this.children=[new mo(l)],this.children[0].parent=this}},collapse:function(e){for(var t=0;t50){for(var a=i.lines.length%25+25,l=a;l10);e.parent.maybeSpill()}},iterN:function(e,t,n){for(var r=0;r0||0==a&&!1!==o.clearWhenEmpty)return o;if(o.replacedWith&&(o.collapsed=!0,o.widgetNode=E("span",[o.replacedWith],"CodeMirror-widget"),r.handleMouseEvents||o.widgetNode.setAttribute("cm-ignore-events","true"),r.insertLeft&&(o.widgetNode.insertLeft=!0)),o.collapsed){if(_e(e,t.line,t,n,o)||t.line!=n.line&&_e(e,n.line,t,n,o))throw new Error("Inserting collapsed marker partially overlapping an existing one");Le=!0}o.addToHistory&&Bi(e,{from:t,to:n,origin:"markText"},e.sel,NaN);var l,s=t.line,c=e.cm;if(e.iter(s,n.line+1,function(e){c&&o.collapsed&&!c.options.lineWrapping&&He(e)==c.display.maxLine&&(l=!0),o.collapsed&&s!=t.line&&ue(e,0),function(e,t){e.markedSpans=e.markedSpans?e.markedSpans.concat([t]):[t],t.marker.attachLine(e)}(e,new Me(o,s==t.line?t.ch:null,s==n.line?n.ch:null)),++s}),o.collapsed&&e.iter(t.line,n.line+1,function(t){Ue(e,t)&&ue(t,0)}),o.clearOnEnter&&et(o,"beforeCursorEnter",function(){return o.clear()}),o.readOnly&&(Se=!0,(e.history.done.length||e.history.undone.length)&&e.clearHistory()),o.collapsed&&(o.id=++bo,o.atomic=!0),c){if(l&&(c.curOp.updateMaxLine=!0),o.collapsed)Zr(c,t.line,n.line+1);else if(o.className||o.title||o.startStyle||o.endStyle||o.css)for(var u=t.line;u<=n.line;u++)Jr(c,u,"text");o.atomic&&Zi(c.doc),sn(c,"markerAdded",c,o)}return o}xo.prototype.clear=function(){if(!this.explicitlyCleared){var e=this.doc.cm,t=e&&!e.curOp;if(t&&Hr(e),at(this,"clear")){var n=this.find();n&&sn(this,"clear",n.from,n.to)}for(var r=null,i=null,o=0;oe.display.maxLineLength&&(e.display.maxLine=c,e.display.maxLineLength=u,e.display.maxLineChanged=!0)}null!=r&&e&&this.collapsed&&Zr(e,r,i+1),this.lines.length=0,this.explicitlyCleared=!0,this.atomic&&this.doc.cantEdit&&(this.doc.cantEdit=!1,e&&Zi(e.doc)),e&&sn(e,"markerCleared",e,this,r,i),t&&Kr(e),this.parent&&this.parent.clear()}},xo.prototype.find=function(e,t){var n,r;null==e&&"bookmark"==this.type&&(e=1);for(var i=0;i=0;s--)io(this,r[s]);l?$i(this,l):this.cm&&Mr(this.cm)}),undo:Yr(function(){ao(this,"undo")}),redo:Yr(function(){ao(this,"redo")}),undoSelection:Yr(function(){ao(this,"undo",!0)}),redoSelection:Yr(function(){ao(this,"redo",!0)}),setExtending:function(e){this.extend=e},getExtending:function(){return this.extend},historySize:function(){for(var e=this.history,t=0,n=0,r=0;r=e.ch)&&t.push(i.marker.parent||i.marker)}return t},findMarks:function(e,t,n){e=ke(this,e),t=ke(this,t);var r=[],i=e.line;return this.iter(e.line,t.line+1,function(o){var a=o.markedSpans;if(a)for(var l=0;l=s.to||null==s.from&&i!=e.line||null!=s.from&&i==t.line&&s.from>=t.ch||n&&!n(s.marker)||r.push(s.marker.parent||s.marker)}++i}),r},getAllMarks:function(){var e=[];return this.iter(function(t){var n=t.markedSpans;if(n)for(var r=0;re)return t=e,!0;e-=o,++n}),ke(this,me(n,t))},indexFromPos:function(e){var t=(e=ke(this,e)).ch;if(e.linet&&(t=e.from),null!=e.to&&e.to-1)return t.state.draggingText(e),void setTimeout(function(){return t.display.input.focus()},20);try{var u=e.dataTransfer.getData("Text");if(u){var f;if(t.state.draggingText&&!t.state.draggingText.copy&&(f=t.listSelections()),Xi(t.doc,xi(n,n)),f)for(var d=0;d=0;t--)co(e.doc,"",r[t].from,r[t].to,"+delete");Mr(e)})}function $o(e,t,n){var r=oe(e.text,t+n,n);return r<0||r>e.text.length?null:r}function Go(e,t,n){var r=$o(e,t.ch,n);return null==r?null:new me(t.line,r,n<0?"after":"before")}function Xo(e,t,n,r,i){if(e){var o=Je(n,t.doc.direction);if(o){var a,l=i<0?X(o):o[0],s=i<0==(1==l.level),c=s?"after":"before";if(l.level>0||"rtl"==t.doc.direction){var u=Pn(t,n);a=i<0?n.text.length-1:0;var f=In(t,u,a).top;a=ae(function(e){return In(t,u,e).top==f},i<0==(1==l.level)?l.from:l.to-1,a),"before"==c&&(a=$o(n,a,1))}else a=i<0?l.to:l.from;return new me(r,a,c)}}return new me(r,i<0?n.text.length:0,i<0?"before":"after")}Wo.basic={Left:"goCharLeft",Right:"goCharRight",Up:"goLineUp",Down:"goLineDown",End:"goLineEnd",Home:"goLineStartSmart",PageUp:"goPageUp",PageDown:"goPageDown",Delete:"delCharAfter",Backspace:"delCharBefore","Shift-Backspace":"delCharBefore",Tab:"defaultTab","Shift-Tab":"indentAuto",Enter:"newlineAndIndent",Insert:"toggleOverwrite",Esc:"singleSelection"},Wo.pcDefault={"Ctrl-A":"selectAll","Ctrl-D":"deleteLine","Ctrl-Z":"undo","Shift-Ctrl-Z":"redo","Ctrl-Y":"redo","Ctrl-Home":"goDocStart","Ctrl-End":"goDocEnd","Ctrl-Up":"goLineUp","Ctrl-Down":"goLineDown","Ctrl-Left":"goGroupLeft","Ctrl-Right":"goGroupRight","Alt-Left":"goLineStart","Alt-Right":"goLineEnd","Ctrl-Backspace":"delGroupBefore","Ctrl-Delete":"delGroupAfter","Ctrl-S":"save","Ctrl-F":"find","Ctrl-G":"findNext","Shift-Ctrl-G":"findPrev","Shift-Ctrl-F":"replace","Shift-Ctrl-R":"replaceAll","Ctrl-[":"indentLess","Ctrl-]":"indentMore","Ctrl-U":"undoSelection","Shift-Ctrl-U":"redoSelection","Alt-U":"redoSelection",fallthrough:"basic"},Wo.emacsy={"Ctrl-F":"goCharRight","Ctrl-B":"goCharLeft","Ctrl-P":"goLineUp","Ctrl-N":"goLineDown","Alt-F":"goWordRight","Alt-B":"goWordLeft","Ctrl-A":"goLineStart","Ctrl-E":"goLineEnd","Ctrl-V":"goPageDown","Shift-Ctrl-V":"goPageUp","Ctrl-D":"delCharAfter","Ctrl-H":"delCharBefore","Alt-D":"delWordAfter","Alt-Backspace":"delWordBefore","Ctrl-K":"killLine","Ctrl-T":"transposeChars","Ctrl-O":"openLine"},Wo.macDefault={"Cmd-A":"selectAll","Cmd-D":"deleteLine","Cmd-Z":"undo","Shift-Cmd-Z":"redo","Cmd-Y":"redo","Cmd-Home":"goDocStart","Cmd-Up":"goDocStart","Cmd-End":"goDocEnd","Cmd-Down":"goDocEnd","Alt-Left":"goGroupLeft","Alt-Right":"goGroupRight","Cmd-Left":"goLineLeft","Cmd-Right":"goLineRight","Alt-Backspace":"delGroupBefore","Ctrl-Alt-Backspace":"delGroupAfter","Alt-Delete":"delGroupAfter","Cmd-S":"save","Cmd-F":"find","Cmd-G":"findNext","Shift-Cmd-G":"findPrev","Cmd-Alt-F":"replace","Shift-Cmd-Alt-F":"replaceAll","Cmd-[":"indentLess","Cmd-]":"indentMore","Cmd-Backspace":"delWrappedLineLeft","Cmd-Delete":"delWrappedLineRight","Cmd-U":"undoSelection","Shift-Cmd-U":"redoSelection","Ctrl-Up":"goDocStart","Ctrl-Down":"goDocEnd",fallthrough:["basic","emacsy"]},Wo.default=y?Wo.macDefault:Wo.pcDefault;var Yo={selectAll:no,singleSelection:function(e){return e.setSelection(e.getCursor("anchor"),e.getCursor("head"),j)},killLine:function(e){return qo(e,function(t){if(t.empty()){var n=le(e.doc,t.head.line).text.length;return t.head.ch==n&&t.head.line0)i=new me(i.line,i.ch+1),e.replaceRange(o.charAt(i.ch-1)+o.charAt(i.ch-2),me(i.line,i.ch-2),i,"+transpose");else if(i.line>e.doc.first){var a=le(e.doc,i.line-1).text;a&&(i=new me(i.line,1),e.replaceRange(o.charAt(0)+e.doc.lineSeparator()+a.charAt(a.length-1),me(i.line-1,a.length-1),i,"+transpose"))}n.push(new yi(i,i))}e.setSelections(n)})},newlineAndIndent:function(e){return $r(e,function(){for(var t=e.listSelections(),n=t.length-1;n>=0;n--)e.replaceRange(e.doc.lineSeparator(),t[n].anchor,t[n].head,"+input");t=e.listSelections();for(var r=0;r-1&&(ge((i=c.ranges[i]).from(),t)<0||t.xRel>0)&&(ge(i.to(),t)>0||t.xRel<0)?function(e,t,n,r){var i=e.display,o=!1,c=Gr(e,function(t){s&&(i.scroller.draggable=!1),e.state.draggingText=!1,nt(i.wrapper.ownerDocument,"mouseup",c),nt(i.wrapper.ownerDocument,"mousemove",u),nt(i.scroller,"dragstart",f),nt(i.scroller,"drop",c),o||(st(t),r.addNew||ji(e.doc,n,null,null,r.extend),s||a&&9==l?setTimeout(function(){i.wrapper.ownerDocument.body.focus(),i.input.focus()},20):i.input.focus())}),u=function(e){o=o||Math.abs(t.clientX-e.clientX)+Math.abs(t.clientY-e.clientY)>=10},f=function(){return o=!0};s&&(i.scroller.draggable=!0),e.state.draggingText=c,c.copy=!r.moveOnDrag,i.scroller.dragDrop&&i.scroller.dragDrop(),et(i.wrapper.ownerDocument,"mouseup",c),et(i.wrapper.ownerDocument,"mousemove",u),et(i.scroller,"dragstart",f),et(i.scroller,"drop",c),gr(e),setTimeout(function(){return i.input.focus()},20)}(e,r,t,o):function(e,t,n,r){var i=e.display,o=e.doc;st(t);var a,l,s=o.sel,c=s.ranges;if(r.addNew&&!r.extend?(l=o.sel.contains(n),a=l>-1?c[l]:new yi(n,n)):(a=o.sel.primary(),l=o.sel.primIndex),"rectangle"==r.unit)r.addNew||(a=new yi(n,n)),n=lr(e,t,!0,!0),l=-1;else{var u=da(e,n,r.unit);a=r.extend?Ki(a,u.anchor,u.head,r.extend):u}r.addNew?-1==l?(l=c.length,Gi(o,bi(c.concat([a]),l),{scroll:!1,origin:"*mouse"})):c.length>1&&c[l].empty()&&"char"==r.unit&&!r.extend?(Gi(o,bi(c.slice(0,l).concat(c.slice(l+1)),0),{scroll:!1,origin:"*mouse"}),s=o.sel):Vi(o,l,a,U):(l=0,Gi(o,new vi([a],0),U),s=o.sel);var f=n;function d(t){if(0!=ge(f,t))if(f=t,"rectangle"==r.unit){for(var i=[],c=e.options.tabSize,u=W(le(o,n.line).text,n.ch,c),d=W(le(o,t.line).text,t.ch,c),h=Math.min(u,d),p=Math.max(u,d),m=Math.min(n.line,t.line),g=Math.min(e.lastLine(),Math.max(n.line,t.line));m<=g;m++){var v=le(o,m).text,y=q(v,h,c);h==p?i.push(new yi(me(m,y),me(m,y))):v.length>y&&i.push(new yi(me(m,y),me(m,q(v,p,c))))}i.length||i.push(new yi(n,n)),Gi(o,bi(s.ranges.slice(0,l).concat(i),l),{origin:"*mouse",scroll:!1}),e.scrollIntoView(t)}else{var b,x=a,w=da(e,t,r.unit),k=x.anchor;ge(w.anchor,k)>0?(b=w.head,k=xe(x.from(),w.anchor)):(b=w.anchor,k=be(x.to(),w.head));var C=s.ranges.slice(0);C[l]=function(e,t){var n=t.anchor,r=t.head,i=le(e.doc,n.line);if(0==ge(n,r)&&n.sticky==r.sticky)return t;var o=Je(i);if(!o)return t;var a=Ye(o,n.ch,n.sticky),l=o[a];if(l.from!=n.ch&&l.to!=n.ch)return t;var s,c=a+(l.from==n.ch==(1!=l.level)?0:1);if(0==c||c==o.length)return t;if(r.line!=n.line)s=(r.line-n.line)*("ltr"==e.doc.direction?1:-1)>0;else{var u=Ye(o,r.ch,r.sticky),f=u-a||(r.ch-n.ch)*(1==l.level?-1:1);s=u==c-1||u==c?f<0:f>0}var d=o[c+(s?-1:0)],h=s==(1==d.level),p=h?d.from:d.to,m=h?"after":"before";return n.ch==p&&n.sticky==m?t:new yi(new me(n.line,p,m),r)}(e,new yi(ke(o,k),b)),Gi(o,bi(C,l),U)}}var h=i.wrapper.getBoundingClientRect(),p=0;function m(t){e.state.selectingText=!1,p=1/0,st(t),i.input.focus(),nt(i.wrapper.ownerDocument,"mousemove",g),nt(i.wrapper.ownerDocument,"mouseup",v),o.history.lastSelOrigin=null}var g=Gr(e,function(t){0!==t.buttons&&ht(t)?function t(n){var a=++p,l=lr(e,n,!0,"rectangle"==r.unit);if(l)if(0!=ge(l,f)){e.curOp.focus=P(),d(l);var s=wr(i,o);(l.line>=s.to||l.lineh.bottom?20:0;c&&setTimeout(Gr(e,function(){p==a&&(i.scroller.scrollTop+=c,t(n))}),50)}}(t):m(t)}),v=Gr(e,m);e.state.selectingText=v,et(i.wrapper.ownerDocument,"mousemove",g),et(i.wrapper.ownerDocument,"mouseup",v)}(e,r,t,o)}(t,r,o,e):dt(e)==n.scroller&&st(e):2==i?(r&&ji(t.doc,r),setTimeout(function(){return n.input.focus()},20)):3==i&&(C?ma(t,e):gr(t)))}}function da(e,t,n){if("char"==n)return new yi(t,t);if("word"==n)return e.findWordAt(t);if("line"==n)return new yi(me(t.line,0),ke(e.doc,me(t.line+1,0)));var r=n(e,t);return new yi(r.from,r.to)}function ha(e,t,n,r){var i,o;if(t.touches)i=t.touches[0].clientX,o=t.touches[0].clientY;else try{i=t.clientX,o=t.clientY}catch(t){return!1}if(i>=Math.floor(e.display.gutters.getBoundingClientRect().right))return!1;r&&st(t);var a=e.display,l=a.lineDiv.getBoundingClientRect();if(o>l.bottom||!at(e,n))return ut(t);o-=l.top-a.viewOffset;for(var s=0;s=i){var u=de(e.doc,o),f=e.options.gutters[s];return rt(e,n,e,u,f,t),ut(t)}}}function pa(e,t){return ha(e,t,"gutterClick",!0)}function ma(e,t){kn(e.display,t)||function(e,t){return!!at(e,"gutterContextMenu")&&ha(e,t,"gutterContextMenu",!1)}(e,t)||it(e,t,"contextmenu")||e.display.input.onContextMenu(t)}function ga(e){e.display.wrapper.className=e.display.wrapper.className.replace(/\s*cm-s-\S+/g,"")+e.options.theme.replace(/(^|\s)\s*/g," cm-s-"),_n(e)}ua.prototype.compare=function(e,t,n){return this.time+400>e&&0==ge(t,this.pos)&&n==this.button};var va={toString:function(){return"CodeMirror.Init"}},ya={},ba={};function xa(e){ui(e),Zr(e),kr(e)}function wa(e,t,n){var r=n&&n!=va;if(!t!=!r){var i=e.display.dragFunctions,o=t?et:nt;o(e.display.scroller,"dragstart",i.start),o(e.display.scroller,"dragenter",i.enter),o(e.display.scroller,"dragover",i.over),o(e.display.scroller,"dragleave",i.leave),o(e.display.scroller,"drop",i.drop)}}function ka(e){e.options.lineWrapping?(I(e.display.wrapper,"CodeMirror-wrap"),e.display.sizer.style.minWidth="",e.display.sizerWidth=null):(M(e.display.wrapper,"CodeMirror-wrap"),Ge(e)),ar(e),Zr(e),_n(e),setTimeout(function(){return Dr(e)},100)}function Ca(e,t){var r=this;if(!(this instanceof Ca))return new Ca(e,t);this.options=t=t?F(t):{},F(ya,t,!1),fi(t);var i=t.value;"string"==typeof i&&(i=new Mo(i,t.mode,null,t.lineSeparator,t.direction)),this.doc=i;var o=new Ca.inputStyles[t.inputStyle](this),c=this.display=new function(e,t,r){var i=this;this.input=r,i.scrollbarFiller=O("div",null,"CodeMirror-scrollbar-filler"),i.scrollbarFiller.setAttribute("cm-not-content","true"),i.gutterFiller=O("div",null,"CodeMirror-gutter-filler"),i.gutterFiller.setAttribute("cm-not-content","true"),i.lineDiv=E("div",null,"CodeMirror-code"),i.selectionDiv=O("div",null,null,"position: relative; z-index: 1"),i.cursorDiv=O("div",null,"CodeMirror-cursors"),i.measure=O("div",null,"CodeMirror-measure"),i.lineMeasure=O("div",null,"CodeMirror-measure"),i.lineSpace=E("div",[i.measure,i.lineMeasure,i.selectionDiv,i.cursorDiv,i.lineDiv],null,"position: relative; outline: none");var o=E("div",[i.lineSpace],"CodeMirror-lines");i.mover=O("div",[o],null,"position: relative"),i.sizer=O("div",[i.mover],"CodeMirror-sizer"),i.sizerWidth=null,i.heightForcer=O("div",null,null,"position: absolute; height: "+H+"px; width: 1px;"),i.gutters=O("div",null,"CodeMirror-gutters"),i.lineGutter=null,i.scroller=O("div",[i.sizer,i.heightForcer,i.gutters],"CodeMirror-scroll"),i.scroller.setAttribute("tabIndex","-1"),i.wrapper=O("div",[i.scrollbarFiller,i.gutterFiller,i.scroller],"CodeMirror"),a&&l<8&&(i.gutters.style.zIndex=-1,i.scroller.style.paddingRight=0),s||n&&v||(i.scroller.draggable=!0),e&&(e.appendChild?e.appendChild(i.wrapper):e(i.wrapper)),i.viewFrom=i.viewTo=t.first,i.reportedViewFrom=i.reportedViewTo=t.first,i.view=[],i.renderedView=null,i.externalMeasured=null,i.viewOffset=0,i.lastWrapHeight=i.lastWrapWidth=0,i.updateLineNumbers=null,i.nativeBarWidth=i.barHeight=i.barWidth=0,i.scrollbarsClipped=!1,i.lineNumWidth=i.lineNumInnerWidth=i.lineNumChars=null,i.alignWidgets=!1,i.cachedCharWidth=i.cachedTextHeight=i.cachedPaddingH=null,i.maxLine=null,i.maxLineLength=0,i.maxLineChanged=!1,i.wheelDX=i.wheelDY=i.wheelStartX=i.wheelStartY=null,i.shift=!1,i.selForContextMenu=null,i.activeTouch=null,r.init(i)}(e,i,o);for(var u in c.wrapper.CodeMirror=this,ui(this),ga(this),t.lineWrapping&&(this.display.wrapper.className+=" CodeMirror-wrap"),zr(this),this.state={keyMaps:[],overlays:[],modeGen:0,overwrite:!1,delayingBlurEvent:!1,focused:!1,suppressEdits:!1,pasteIncoming:!1,cutIncoming:!1,selectingText:!1,draggingText:!1,highlight:new z,keySeq:null,specialChars:null},t.autofocus&&!v&&c.input.focus(),a&&l<11&&setTimeout(function(){return r.display.input.reset(!0)},20),function(e){var t=e.display;et(t.scroller,"mousedown",Gr(e,fa)),et(t.scroller,"dblclick",a&&l<11?Gr(e,function(t){if(!it(e,t)){var n=lr(e,t);if(n&&!pa(e,t)&&!kn(e.display,t)){st(t);var r=e.findWordAt(n);ji(e.doc,r.anchor,r.head)}}}):function(t){return it(e,t)||st(t)}),C||et(t.scroller,"contextmenu",function(t){return ma(e,t)});var n,r={end:0};function i(){t.activeTouch&&(n=setTimeout(function(){return t.activeTouch=null},1e3),(r=t.activeTouch).end=+new Date)}function o(e,t){if(null==t.left)return!0;var n=t.left-e.left,r=t.top-e.top;return n*n+r*r>400}et(t.scroller,"touchstart",function(i){if(!it(e,i)&&!function(e){if(1!=e.touches.length)return!1;var t=e.touches[0];return t.radiusX<=1&&t.radiusY<=1}(i)&&!pa(e,i)){t.input.ensurePolled(),clearTimeout(n);var o=+new Date;t.activeTouch={start:o,moved:!1,prev:o-r.end<=300?r:null},1==i.touches.length&&(t.activeTouch.left=i.touches[0].pageX,t.activeTouch.top=i.touches[0].pageY)}}),et(t.scroller,"touchmove",function(){t.activeTouch&&(t.activeTouch.moved=!0)}),et(t.scroller,"touchend",function(n){var r=t.activeTouch;if(r&&!kn(t,n)&&null!=r.left&&!r.moved&&new Date-r.start<300){var a,l=e.coordsChar(t.activeTouch,"page");a=!r.prev||o(r,r.prev)?new yi(l,l):!r.prev.prev||o(r,r.prev.prev)?e.findWordAt(l):new yi(me(l.line,0),ke(e.doc,me(l.line+1,0))),e.setSelection(a.anchor,a.head),e.focus(),st(n)}i()}),et(t.scroller,"touchcancel",i),et(t.scroller,"scroll",function(){t.scroller.clientHeight&&(Er(e,t.scroller.scrollTop),Pr(e,t.scroller.scrollLeft,!0),rt(e,"scroll",e))}),et(t.scroller,"mousewheel",function(t){return gi(e,t)}),et(t.scroller,"DOMMouseScroll",function(t){return gi(e,t)}),et(t.wrapper,"scroll",function(){return t.wrapper.scrollTop=t.wrapper.scrollLeft=0}),t.dragFunctions={enter:function(t){it(e,t)||ft(t)},over:function(t){it(e,t)||(function(e,t){var n=lr(e,t);if(n){var r=document.createDocumentFragment();fr(e,n,r),e.display.dragCursor||(e.display.dragCursor=O("div",null,"CodeMirror-cursors CodeMirror-dragcursors"),e.display.lineSpace.insertBefore(e.display.dragCursor,e.display.cursorDiv)),A(e.display.dragCursor,r)}}(e,t),ft(t))},start:function(t){return function(e,t){if(a&&(!e.state.draggingText||+new Date-To<100))ft(t);else if(!it(e,t)&&!kn(e.display,t)&&(t.dataTransfer.setData("Text",e.getSelection()),t.dataTransfer.effectAllowed="copyMove",t.dataTransfer.setDragImage&&!d)){var n=O("img",null,null,"position: fixed; left: 0; top: 0;");n.src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==",f&&(n.width=n.height=1,e.display.wrapper.appendChild(n),n._top=n.offsetTop),t.dataTransfer.setDragImage(n,0,0),f&&n.parentNode.removeChild(n)}}(e,t)},drop:Gr(e,Ao),leave:function(t){it(e,t)||Oo(e)}};var s=t.input.getField();et(s,"keyup",function(t){return aa.call(e,t)}),et(s,"keydown",Gr(e,oa)),et(s,"keypress",Gr(e,la)),et(s,"focus",function(t){return vr(e,t)}),et(s,"blur",function(t){return yr(e,t)})}(this),Po(),Hr(this),this.curOp.forceUpdate=!0,Ei(this,i),t.autofocus&&!v||this.hasFocus()?setTimeout(D(vr,this),20):yr(this),ba)ba.hasOwnProperty(u)&&ba[u](r,t[u],va);Cr(this),t.finishInit&&t.finishInit(this);for(var h=0;h150)){if(!r)return;n="prev"}}else c=0,n="not";"prev"==n?c=t>o.first?W(le(o,t-1).text,null,a):0:"add"==n?c=s+e.options.indentUnit:"subtract"==n?c=s-e.options.indentUnit:"number"==typeof n&&(c=s+n),c=Math.max(0,c);var f="",d=0;if(e.options.indentWithTabs)for(var h=Math.floor(c/a);h;--h)d+=a,f+="\t";if(d1)if(Ma&&Ma.text.join("\n")==t){if(r.ranges.length%Ma.text.length==0){c=[];for(var u=0;u=0;f--){var d=r.ranges[f],h=d.from(),p=d.to();d.empty()&&(n&&n>0?h=me(h.line,h.ch-n):e.state.overwrite&&!l?p=me(p.line,Math.min(le(o,p.line).text.length,p.ch+X(s).length)):Ma&&Ma.lineWise&&Ma.text.join("\n")==t&&(h=p=me(h.line,0))),a=e.curOp.updateInput;var m={from:h,to:p,text:c?c[f%c.length]:s,origin:i||(l?"paste":e.state.cutIncoming?"cut":"+input")};io(e.doc,m),sn(e,"inputRead",e,m)}t&&!l&&Ea(e,t),Mr(e),e.curOp.updateInput=a,e.curOp.typing=!0,e.state.pasteIncoming=e.state.cutIncoming=!1}function Oa(e,t){var n=e.clipboardData&&e.clipboardData.getData("Text");if(n)return e.preventDefault(),t.isReadOnly()||t.options.disableInput||$r(t,function(){return Aa(t,n,0,null,"paste")}),!0}function Ea(e,t){if(e.options.electricChars&&e.options.smartIndent)for(var n=e.doc.sel,r=n.ranges.length-1;r>=0;r--){var i=n.ranges[r];if(!(i.head.ch>100||r&&n.ranges[r-1].head.line==i.head.line)){var o=e.getModeAt(i.head),a=!1;if(o.electricChars){for(var l=0;l-1){a=La(e,i.head.line,"smart");break}}else o.electricInput&&o.electricInput.test(le(e.doc,i.head.line).text.slice(0,i.head.ch))&&(a=La(e,i.head.line,"smart"));a&&sn(e,"electricInput",e,i.head.line)}}}function Na(e){for(var t=[],n=[],r=0;r=t.text.length?(n.ch=t.text.length,n.sticky="before"):n.ch<=0&&(n.ch=0,n.sticky="after");var o=Ye(i,n.ch,n.sticky),a=i[o];if("ltr"==e.doc.direction&&a.level%2==0&&(r>0?a.to>n.ch:a.from=a.from&&d>=u.begin)){var h=f?"before":"after";return new me(n.line,d,h)}}var p=function(e,t,r){for(var o=function(e,t){return t?new me(n.line,s(e,1),"before"):new me(n.line,e,"after")};e>=0&&e0==(1!=a.level),c=l?r.begin:s(r.end,-1);if(a.from<=c&&c0?u.end:s(u.begin,-1);return null==g||r>0&&g==t.text.length||!(m=p(r>0?0:i.length-1,r,c(g)))?null:m}(e.cm,l,t,n):Go(l,t,n))){if(r||((a=t.line+n)=e.first+e.size||(t=new me(a,t.ch,t.sticky),!(l=le(e,a)))))return!1;t=Xo(i,e.cm,l,t.line,n)}else t=o;return!0}if("char"==r)s();else if("column"==r)s(!0);else if("word"==r||"group"==r)for(var c=null,u="group"==r,f=e.cm&&e.cm.getHelper(t,"wordChars"),d=!0;!(n<0)||s(!d);d=!1){var h=l.text.charAt(t.ch)||"\n",p=te(h,f)?"w":u&&"\n"==h?"n":!u||/\s/.test(h)?null:"p";if(!u||d||p||(p="s"),c&&c!=p){n<0&&(n=1,s(),t.sticky="after");break}if(p&&(c=p),n>0&&!s(!d))break}var m=eo(e,t,o,a,!0);return ve(o,m)&&(m.hitSide=!0),m}function Ba(e,t,n,r){var i,o,a=e.doc,l=t.left;if("page"==r){var s=Math.min(e.display.wrapper.clientHeight,window.innerHeight||document.documentElement.clientHeight),c=Math.max(s-.5*tr(e.display),3);i=(n>0?t.bottom:t.top)+n*c}else"line"==r&&(i=n>0?t.bottom+3:t.top-3);for(;(o=Yn(e,l,i)).outside;){if(n<0?i<=0:i>=a.height){o.hitSide=!0;break}i+=5*n}return o}var Da=function(e){this.cm=e,this.lastAnchorNode=this.lastAnchorOffset=this.lastFocusNode=this.lastFocusOffset=null,this.polling=new z,this.composing=null,this.gracePeriod=!1,this.readDOMTimeout=null};function Fa(e,t){var n=Nn(e,t.line);if(!n||n.hidden)return null;var r=le(e.doc,t.line),i=On(n,r,t.line),o=Je(r,e.doc.direction),a="left";if(o){var l=Ye(o,t.ch);a=l%2?"right":"left"}var s=Dn(i.map,t.ch,a);return s.offset="right"==s.collapse?s.end:s.start,s}function Wa(e,t){return t&&(e.bad=!0),e}function za(e,t,n){var r;if(t==e.display.lineDiv){if(!(r=e.display.lineDiv.childNodes[n]))return Wa(e.clipPos(me(e.display.viewTo-1)),!0);t=null,n=0}else for(r=t;;r=r.parentNode){if(!r||r==e.display.lineDiv)return null;if(r.parentNode&&r.parentNode==e.display.lineDiv)break}for(var i=0;i=t.display.viewTo||o.line=t.display.viewFrom&&Fa(t,i)||{node:s[0].measure.map[2],offset:0},u=o.liner.firstLine()&&(a=me(a.line-1,le(r.doc,a.line-1).length)),l.ch==le(r.doc,l.line).text.length&&l.linei.viewTo-1)return!1;a.line==i.viewFrom||0==(e=sr(r,a.line))?(t=fe(i.view[0].line),n=i.view[0].node):(t=fe(i.view[e].line),n=i.view[e-1].node.nextSibling);var s,c,u=sr(r,l.line);if(u==i.view.length-1?(s=i.viewTo-1,c=i.lineDiv.lastChild):(s=fe(i.view[u+1].line)-1,c=i.view[u+1].node.previousSibling),!n)return!1;for(var f=r.doc.splitLines(function(e,t,n,r,i){var o="",a=!1,l=e.doc.lineSeparator(),s=!1;function c(){a&&(o+=l,s&&(o+=l),a=s=!1)}function u(e){e&&(c(),o+=e)}function f(t){if(1==t.nodeType){var n=t.getAttribute("cm-text");if(n)return void u(n);var o,d=t.getAttribute("cm-marker");if(d){var h=e.findMarks(me(r,0),me(i+1,0),(g=+d,function(e){return e.id==g}));return void(h.length&&(o=h[0].find(0))&&u(se(e.doc,o.from,o.to).join(l)))}if("false"==t.getAttribute("contenteditable"))return;var p=/^(pre|div|p|li|table|br)$/i.test(t.nodeName);if(!/^br$/i.test(t.nodeName)&&0==t.textContent.length)return;p&&c();for(var m=0;m1&&d.length>1;)if(X(f)==X(d))f.pop(),d.pop(),s--;else{if(f[0]!=d[0])break;f.shift(),d.shift(),t++}for(var h=0,p=0,m=f[0],g=d[0],v=Math.min(m.length,g.length);ha.ch&&y.charCodeAt(y.length-p-1)==b.charCodeAt(b.length-p-1);)h--,p++;f[f.length-1]=y.slice(0,y.length-p).replace(/^\u200b+/,""),f[0]=f[0].slice(h).replace(/\u200b+$/,"");var w=me(t,h),k=me(s,d.length?X(d).length-p:0);return f.length>1||f[0]||ge(w,k)?(co(r.doc,f,w,k,"+input"),!0):void 0},Da.prototype.ensurePolled=function(){this.forceCompositionEnd()},Da.prototype.reset=function(){this.forceCompositionEnd()},Da.prototype.forceCompositionEnd=function(){this.composing&&(clearTimeout(this.readDOMTimeout),this.composing=null,this.updateFromDOM(),this.div.blur(),this.div.focus())},Da.prototype.readFromDOMSoon=function(){var e=this;null==this.readDOMTimeout&&(this.readDOMTimeout=setTimeout(function(){if(e.readDOMTimeout=null,e.composing){if(!e.composing.done)return;e.composing=null}e.updateFromDOM()},80))},Da.prototype.updateFromDOM=function(){var e=this;!this.cm.isReadOnly()&&this.pollContent()||$r(this.cm,function(){return Zr(e.cm)})},Da.prototype.setUneditable=function(e){e.contentEditable="false"},Da.prototype.onKeyPress=function(e){0==e.charCode||this.composing||(e.preventDefault(),this.cm.isReadOnly()||Gr(this.cm,Aa)(this.cm,String.fromCharCode(null==e.charCode?e.keyCode:e.charCode),0))},Da.prototype.readOnlyChanged=function(e){this.div.contentEditable=String("nocursor"!=e)},Da.prototype.onContextMenu=function(){},Da.prototype.resetPosition=function(){},Da.prototype.needsContentAttribute=!0;var Ha=function(e){this.cm=e,this.prevInput="",this.pollingFast=!1,this.polling=new z,this.hasSelection=!1,this.composing=null};Ha.prototype.init=function(e){var t=this,n=this,r=this.cm;this.createField(e);var i=this.textarea;function o(e){if(!it(r,e)){if(r.somethingSelected())Ta({lineWise:!1,text:r.getSelections()});else{if(!r.options.lineWiseCopyCut)return;var t=Na(r);Ta({lineWise:!0,text:t.text}),"cut"==e.type?r.setSelections(t.ranges,null,j):(n.prevInput="",i.value=t.text.join("\n"),B(i))}"cut"==e.type&&(r.state.cutIncoming=!0)}}e.wrapper.insertBefore(this.wrapper,e.wrapper.firstChild),m&&(i.style.width="0px"),et(i,"input",function(){a&&l>=9&&t.hasSelection&&(t.hasSelection=null),n.poll()}),et(i,"paste",function(e){it(r,e)||Oa(e,r)||(r.state.pasteIncoming=!0,n.fastPoll())}),et(i,"cut",o),et(i,"copy",o),et(e.scroller,"paste",function(t){kn(e,t)||it(r,t)||(r.state.pasteIncoming=!0,n.focus())}),et(e.lineSpace,"selectstart",function(t){kn(e,t)||st(t)}),et(i,"compositionstart",function(){var e=r.getCursor("from");n.composing&&n.composing.range.clear(),n.composing={start:e,range:r.markText(e,r.getCursor("to"),{className:"CodeMirror-composing"})}}),et(i,"compositionend",function(){n.composing&&(n.poll(),n.composing.range.clear(),n.composing=null)})},Ha.prototype.createField=function(e){this.wrapper=Ia(),this.textarea=this.wrapper.firstChild},Ha.prototype.prepareSelection=function(){var e=this.cm,t=e.display,n=e.doc,r=ur(e);if(e.options.moveInputWithCursor){var i=$n(e,n.sel.primary().head,"div"),o=t.wrapper.getBoundingClientRect(),a=t.lineDiv.getBoundingClientRect();r.teTop=Math.max(0,Math.min(t.wrapper.clientHeight-10,i.top+a.top-o.top)),r.teLeft=Math.max(0,Math.min(t.wrapper.clientWidth-10,i.left+a.left-o.left))}return r},Ha.prototype.showSelection=function(e){var t=this.cm,n=t.display;A(n.cursorDiv,e.cursors),A(n.selectionDiv,e.selection),null!=e.teTop&&(this.wrapper.style.top=e.teTop+"px",this.wrapper.style.left=e.teLeft+"px")},Ha.prototype.reset=function(e){if(!this.contextMenuPending&&!this.composing){var t=this.cm;if(t.somethingSelected()){this.prevInput="";var n=t.getSelection();this.textarea.value=n,t.state.focused&&B(this.textarea),a&&l>=9&&(this.hasSelection=n)}else e||(this.prevInput=this.textarea.value="",a&&l>=9&&(this.hasSelection=null))}},Ha.prototype.getField=function(){return this.textarea},Ha.prototype.supportsTouch=function(){return!1},Ha.prototype.focus=function(){if("nocursor"!=this.cm.options.readOnly&&(!v||P()!=this.textarea))try{this.textarea.focus()}catch(e){}},Ha.prototype.blur=function(){this.textarea.blur()},Ha.prototype.resetPosition=function(){this.wrapper.style.top=this.wrapper.style.left=0},Ha.prototype.receivedFocus=function(){this.slowPoll()},Ha.prototype.slowPoll=function(){var e=this;this.pollingFast||this.polling.set(this.cm.options.pollInterval,function(){e.poll(),e.cm.state.focused&&e.slowPoll()})},Ha.prototype.fastPoll=function(){var e=!1,t=this;t.pollingFast=!0,t.polling.set(20,function n(){var r=t.poll();r||e?(t.pollingFast=!1,t.slowPoll()):(e=!0,t.polling.set(60,n))})},Ha.prototype.poll=function(){var e=this,t=this.cm,n=this.textarea,r=this.prevInput;if(this.contextMenuPending||!t.state.focused||wt(n)&&!r&&!this.composing||t.isReadOnly()||t.options.disableInput||t.state.keySeq)return!1;var i=n.value;if(i==r&&!t.somethingSelected())return!1;if(a&&l>=9&&this.hasSelection===i||y&&/[\uf700-\uf7ff]/.test(i))return t.display.input.reset(),!1;if(t.doc.sel==t.display.selForContextMenu){var o=i.charCodeAt(0);if(8203!=o||r||(r="​"),8666==o)return this.reset(),this.cm.execCommand("undo")}for(var s=0,c=Math.min(r.length,i.length);s1e3||i.indexOf("\n")>-1?n.value=e.prevInput="":e.prevInput=i,e.composing&&(e.composing.range.clear(),e.composing.range=t.markText(e.composing.start,t.getCursor("to"),{className:"CodeMirror-composing"}))}),!0},Ha.prototype.ensurePolled=function(){this.pollingFast&&this.poll()&&(this.pollingFast=!1)},Ha.prototype.onKeyPress=function(){a&&l>=9&&(this.hasSelection=null),this.fastPoll()},Ha.prototype.onContextMenu=function(e){var t=this,n=t.cm,r=n.display,i=t.textarea,o=lr(n,e),c=r.scroller.scrollTop;if(o&&!f){var u=n.options.resetSelectionOnContextMenu;u&&-1==n.doc.sel.contains(o)&&Gr(n,Gi)(n.doc,xi(o),j);var d=i.style.cssText,h=t.wrapper.style.cssText;t.wrapper.style.cssText="position: absolute";var p,m=t.wrapper.getBoundingClientRect();if(i.style.cssText="position: absolute; width: 30px; height: 30px;\n top: "+(e.clientY-m.top-5)+"px; left: "+(e.clientX-m.left-5)+"px;\n z-index: 1000; background: "+(a?"rgba(255, 255, 255, .05)":"transparent")+";\n outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);",s&&(p=window.scrollY),r.input.focus(),s&&window.scrollTo(null,p),r.input.reset(),n.somethingSelected()||(i.value=t.prevInput=" "),t.contextMenuPending=!0,r.selForContextMenu=n.doc.sel,clearTimeout(r.detectingSelectAll),a&&l>=9&&v(),C){ft(e);var g=function(){nt(window,"mouseup",g),setTimeout(y,20)};et(window,"mouseup",g)}else setTimeout(y,50)}function v(){if(null!=i.selectionStart){var e=n.somethingSelected(),o="​"+(e?i.value:"");i.value="⇚",i.value=o,t.prevInput=e?"":"​",i.selectionStart=1,i.selectionEnd=o.length,r.selForContextMenu=n.doc.sel}}function y(){if(t.contextMenuPending=!1,t.wrapper.style.cssText=h,i.style.cssText=d,a&&l<9&&r.scrollbars.setScrollTop(r.scroller.scrollTop=c),null!=i.selectionStart){(!a||a&&l<9)&&v();var e=0,o=function(){r.selForContextMenu==n.doc.sel&&0==i.selectionStart&&i.selectionEnd>0&&"​"==t.prevInput?Gr(n,no)(n):e++<10?r.detectingSelectAll=setTimeout(o,500):(r.selForContextMenu=null,r.input.reset())};r.detectingSelectAll=setTimeout(o,200)}}},Ha.prototype.readOnlyChanged=function(e){e||this.reset(),this.textarea.disabled="nocursor"==e},Ha.prototype.setUneditable=function(){},Ha.prototype.needsContentAttribute=!1,function(e){var t=e.optionHandlers;function n(n,r,i,o){e.defaults[n]=r,i&&(t[n]=o?function(e,t,n){n!=va&&i(e,t,n)}:i)}e.defineOption=n,e.Init=va,n("value","",function(e,t){return e.setValue(t)},!0),n("mode",null,function(e,t){e.doc.modeOption=t,Li(e)},!0),n("indentUnit",2,Li,!0),n("indentWithTabs",!1),n("smartIndent",!0),n("tabSize",4,function(e){Mi(e),_n(e),Zr(e)},!0),n("lineSeparator",null,function(e,t){if(e.doc.lineSep=t,t){var n=[],r=e.doc.first;e.doc.iter(function(e){for(var i=0;;){var o=e.text.indexOf(t,i);if(-1==o)break;i=o+t.length,n.push(me(r,o))}r++});for(var i=n.length-1;i>=0;i--)co(e.doc,t,n[i],me(n[i].line,n[i].ch+t.length))}}),n("specialChars",/[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b-\u200f\u2028\u2029\ufeff]/g,function(e,t,n){e.state.specialChars=new RegExp(t.source+(t.test("\t")?"":"|\t"),"g"),n!=va&&e.refresh()}),n("specialCharPlaceholder",Jt,function(e){return e.refresh()},!0),n("electricChars",!0),n("inputStyle",v?"contenteditable":"textarea",function(){throw new Error("inputStyle can not (yet) be changed in a running editor")},!0),n("spellcheck",!1,function(e,t){return e.getInputField().spellcheck=t},!0),n("rtlMoveVisually",!x),n("wholeLineUpdateBefore",!0),n("theme","default",function(e){ga(e),xa(e)},!0),n("keyMap","default",function(e,t,n){var r=Vo(t),i=n!=va&&Vo(n);i&&i.detach&&i.detach(e,r),r.attach&&r.attach(e,i||null)}),n("extraKeys",null),n("configureMouse",null),n("lineWrapping",!1,ka,!0),n("gutters",[],function(e){fi(e.options),xa(e)},!0),n("fixedGutter",!0,function(e,t){e.display.gutters.style.left=t?ir(e.display)+"px":"0",e.refresh()},!0),n("coverGutterNextToScrollbar",!1,function(e){return Dr(e)},!0),n("scrollbarStyle","native",function(e){zr(e),Dr(e),e.display.scrollbars.setScrollTop(e.doc.scrollTop),e.display.scrollbars.setScrollLeft(e.doc.scrollLeft)},!0),n("lineNumbers",!1,function(e){fi(e.options),xa(e)},!0),n("firstLineNumber",1,xa,!0),n("lineNumberFormatter",function(e){return e},xa,!0),n("showCursorWhenSelecting",!1,cr,!0),n("resetSelectionOnContextMenu",!0),n("lineWiseCopyCut",!0),n("pasteLinesPerSelection",!0),n("readOnly",!1,function(e,t){"nocursor"==t&&(yr(e),e.display.input.blur()),e.display.input.readOnlyChanged(t)}),n("disableInput",!1,function(e,t){t||e.display.input.reset()},!0),n("dragDrop",!0,wa),n("allowDropFileTypes",null),n("cursorBlinkRate",530),n("cursorScrollMargin",0),n("cursorHeight",1,cr,!0),n("singleCursorHeightPerLine",!0,cr,!0),n("workTime",100),n("workDelay",100),n("flattenSpans",!0,Mi,!0),n("addModeClass",!1,Mi,!0),n("pollInterval",100),n("undoDepth",200,function(e,t){return e.doc.history.undoDepth=t}),n("historyEventDelay",1250),n("viewportMargin",10,function(e){return e.refresh()},!0),n("maxHighlightLength",1e4,Mi,!0),n("moveInputWithCursor",!0,function(e,t){t||e.display.input.resetPosition()}),n("tabindex",null,function(e,t){return e.display.input.getField().tabIndex=t||""}),n("autofocus",null),n("direction","ltr",function(e,t){return e.doc.setDirection(t)},!0)}(Ca),function(e){var t=e.optionHandlers,n=e.helpers={};e.prototype={constructor:e,focus:function(){window.focus(),this.display.input.focus()},setOption:function(e,n){var r=this.options,i=r[e];r[e]==n&&"mode"!=e||(r[e]=n,t.hasOwnProperty(e)&&Gr(this,t[e])(this,n,i),rt(this,"optionChange",this,e))},getOption:function(e){return this.options[e]},getDoc:function(){return this.doc},addKeyMap:function(e,t){this.state.keyMaps[t?"push":"unshift"](Vo(e))},removeKeyMap:function(e){for(var t=this.state.keyMaps,n=0;nn&&(La(this,i.head.line,e,!0),n=i.head.line,r==this.doc.sel.primIndex&&Mr(this));else{var o=i.from(),a=i.to(),l=Math.max(n,o.line);n=Math.min(this.lastLine(),a.line-(a.ch?0:1))+1;for(var s=l;s0&&Vi(this.doc,r,new yi(o,c[r].to()),j)}}}),getTokenAt:function(e,t){return jt(this,e,t)},getLineTokens:function(e,t){return jt(this,me(e),t,!0)},getTokenTypeAt:function(e){e=ke(this.doc,e);var t,n=Ft(this,le(this.doc,e.line)),r=0,i=(n.length-1)/2,o=e.ch;if(0==o)t=n[2];else for(;;){var a=r+i>>1;if((a?n[2*a-1]:0)>=o)i=a;else{if(!(n[2*a+1]o&&(e=o,i=!0),r=le(this.doc,e)}else r=e;return Un(this,r,{top:0,left:0},t||"page",n||i).top+(i?this.doc.height-qe(r):0)},defaultTextHeight:function(){return tr(this.display)},defaultCharWidth:function(){return nr(this.display)},getViewport:function(){return{from:this.display.viewFrom,to:this.display.viewTo}},addWidget:function(e,t,n,r,i){var o,a,l,s=this.display,c=(e=$n(this,ke(this.doc,e))).bottom,u=e.left;if(t.style.position="absolute",t.setAttribute("cm-ignore-events","true"),this.display.input.setUneditable(t),s.sizer.appendChild(t),"over"==r)c=e.top;else if("above"==r||"near"==r){var f=Math.max(s.wrapper.clientHeight,this.doc.height),d=Math.max(s.sizer.clientWidth,s.lineSpace.clientWidth);("above"==r||e.bottom+t.offsetHeight>f)&&e.top>t.offsetHeight?c=e.top-t.offsetHeight:e.bottom+t.offsetHeight<=f&&(c=e.bottom),u+t.offsetWidth>d&&(u=d-t.offsetWidth)}t.style.top=c+"px",t.style.left=t.style.right="","right"==i?(u=s.sizer.clientWidth-t.offsetWidth,t.style.right="0px"):("left"==i?u=0:"middle"==i&&(u=(s.sizer.clientWidth-t.offsetWidth)/2),t.style.left=u+"px"),n&&(o=this,a={left:u,top:c,right:u+t.offsetWidth,bottom:c+t.offsetHeight},null!=(l=Sr(o,a)).scrollTop&&Er(o,l.scrollTop),null!=l.scrollLeft&&Pr(o,l.scrollLeft))},triggerOnKeyDown:Xr(oa),triggerOnKeyPress:Xr(la),triggerOnKeyUp:aa,triggerOnMouseDown:Xr(fa),execCommand:function(e){if(Yo.hasOwnProperty(e))return Yo[e].call(null,this)},triggerElectric:Xr(function(e){Ea(this,e)}),findPosH:function(e,t,n,r){var i=1;t<0&&(i=-1,t=-t);for(var o=ke(this.doc,e),a=0;a0&&l(n.charAt(r-1));)--r;for(;i.5)&&ar(this),rt(this,"refresh",this)}),swapDoc:Xr(function(e){var t=this.doc;return t.cm=null,Ei(this,e),_n(this),this.display.input.reset(),Tr(this,e.scrollLeft,e.scrollTop),this.curOp.forceScroll=!0,sn(this,"swapDoc",this,t),t}),getInputField:function(){return this.display.input.getField()},getWrapperElement:function(){return this.display.wrapper},getScrollerElement:function(){return this.display.scroller},getGutterElement:function(){return this.display.gutters}},lt(e),e.registerHelper=function(t,r,i){n.hasOwnProperty(t)||(n[t]=e[t]={_global:[]}),n[t][r]=i},e.registerGlobalHelper=function(t,r,i,o){e.registerHelper(t,r,o),n[t]._global.push({pred:i,val:o})}}(Ca);var Ka="iter insert remove copy getEditor constructor".split(" ");for(var ja in Mo.prototype)Mo.prototype.hasOwnProperty(ja)&&_(Ka,ja)<0&&(Ca.prototype[ja]=function(e){return function(){return e.apply(this.doc,arguments)}}(Mo.prototype[ja]));return lt(Mo),Ca.inputStyles={textarea:Ha,contenteditable:Da},Ca.defineMode=function(e){Ca.defaults.mode||"null"==e||(Ca.defaults.mode=e),function(e,t){arguments.length>2&&(t.dependencies=Array.prototype.slice.call(arguments,2)),St[e]=t}.apply(this,arguments)},Ca.defineMIME=function(e,t){Lt[e]=t},Ca.defineMode("null",function(){return{token:function(e){return e.skipToEnd()}}}),Ca.defineMIME("text/plain","null"),Ca.defineExtension=function(e,t){Ca.prototype[e]=t},Ca.defineDocExtension=function(e,t){Mo.prototype[e]=t},Ca.fromTextArea=function(e,t){if((t=t?F(t):{}).value=e.value,!t.tabindex&&e.tabIndex&&(t.tabindex=e.tabIndex),!t.placeholder&&e.placeholder&&(t.placeholder=e.placeholder),null==t.autofocus){var n=P();t.autofocus=n==e||null!=e.getAttribute("autofocus")&&n==document.body}function r(){e.value=l.getValue()}var i;if(e.form&&(et(e.form,"submit",r),!t.leaveSubmitMethodAlone)){var o=e.form;i=o.submit;try{var a=o.submit=function(){r(),o.submit=i,o.submit(),o.submit=a}}catch(e){}}t.finishInit=function(t){t.save=r,t.getTextArea=function(){return e},t.toTextArea=function(){t.toTextArea=isNaN,r(),e.parentNode.removeChild(t.getWrapperElement()),e.style.display="",e.form&&(nt(e.form,"submit",r),"function"==typeof e.form.submit&&(e.form.submit=i))}},e.style.display="none";var l=Ca(function(t){return e.parentNode.insertBefore(t,e.nextSibling)},t);return l},function(e){e.off=nt,e.on=et,e.wheelEventPixels=mi,e.Doc=Mo,e.splitLines=xt,e.countColumn=W,e.findColumn=q,e.isWordChar=ee,e.Pass=K,e.signal=rt,e.Line=qt,e.changeEnd=wi,e.scrollbarModel=Wr,e.Pos=me,e.cmpPos=ge,e.modes=St,e.mimeModes=Lt,e.resolveMode=Mt,e.getMode=Tt,e.modeExtensions=At,e.extendMode=Ot,e.copyState=Et,e.startState=Pt,e.innerMode=Nt,e.commands=Yo,e.keyMap=Wo,e.keyName=Uo,e.isModifierKey=Ko,e.lookupKey=Ho,e.normalizeKeyMap=_o,e.StringStream=It,e.SharedTextMarker=ko,e.TextMarker=xo,e.LineWidget=vo,e.e_preventDefault=st,e.e_stopPropagation=ct,e.e_stop=ft,e.addClass=I,e.contains=N,e.rmClass=M,e.keyNames=Ro}(Ca),Ca.version="5.38.0",Ca}()},function(e,t,n){!function(e){"use strict";var t,n,r=e.Pos;function i(e,t){for(var n=function(e){var t=e.flags;return null!=t?t:(e.ignoreCase?"i":"")+(e.global?"g":"")+(e.multiline?"m":"")}(e),r=n,i=0;i>1,l=r(e.slice(0,a)).length;if(l==n)return a;l>n?o=a:i=a+1}}function s(e,s,c,u){var f;this.atOccurrence=!1,this.doc=e,c=c?e.clipPos(c):r(0,0),this.pos={from:c,to:c},"object"==typeof u?f=u.caseFold:(f=u,u=null),"string"==typeof s?(null==f&&(f=!1),this.matches=function(i,o){return(i?function(e,i,o,a){if(!i.length)return null;var s=a?t:n,c=s(i).split(/\r|\n\r?/);e:for(var u=o.line,f=o.ch,d=e.firstLine()-1+c.length;u>=d;u--,f=-1){var h=e.getLine(u);f>-1&&(h=h.slice(0,f));var p=s(h);if(1==c.length){var m=p.lastIndexOf(c[0]);if(-1==m)continue e;return{from:r(u,l(h,p,m,s)),to:r(u,l(h,p,m+c[0].length,s))}}var g=c[c.length-1];if(p.slice(0,g.length)==g){for(var v=1,o=u-c.length+1;v=s;o--,l=-1){var c=e.getLine(o);l>-1&&(c=c.slice(0,l));var u=a(c,t);if(u)return{from:r(o,u.index),to:r(o,u.index+u[0].length),match:u}}}:o)(e,s,n)}:this.matches=function(t,n){return(t?function(e,t,n){t=i(t,"gm");for(var o,l=1,s=n.line,c=e.firstLine();s>=c;){for(var u=0;uc);u++){var f=e.getLine(s++);a=null==a?f:a+"\n"+f}l*=2,t.lastIndex=n.ch;var d=t.exec(a);if(d){var h=a.slice(0,d.index).split("\n"),p=d[0].split("\n"),m=n.line+h.length-1,g=h[h.length-1].length;return{from:r(m,g),to:r(m+p.length-1,1==p.length?g+p[0].length:p[p.length-1].length),match:d}}}})(e,s,n)})}String.prototype.normalize?(t=function(e){return e.normalize("NFD").toLowerCase()},n=function(e){return e.normalize("NFD")}):(t=function(e){return e.toLowerCase()},n=function(e){return e}),s.prototype={findNext:function(){return this.find(!1)},findPrevious:function(){return this.find(!0)},find:function(t){for(var n=this.matches(t,this.doc.clipPos(t?this.pos.from:this.pos.to));n&&0==e.cmpPos(n.from,n.to);)t?n.from.ch?n.from=r(n.from.line,n.from.ch-1):n=n.from.line==this.doc.firstLine()?null:this.matches(t,this.doc.clipPos(r(n.from.line-1))):n.to.ch0);)r.push({anchor:i.from(),head:i.to()});r.length&&this.setSelections(r,0)})}(n(0))},function(e,t,n){!function(e){"use strict";var t={autoSelfClosers:{area:!0,base:!0,br:!0,col:!0,command:!0,embed:!0,frame:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0,menuitem:!0},implicitlyClosed:{dd:!0,li:!0,optgroup:!0,option:!0,p:!0,rp:!0,rt:!0,tbody:!0,td:!0,tfoot:!0,th:!0,tr:!0},contextGrabbers:{dd:{dd:!0,dt:!0},dt:{dd:!0,dt:!0},li:{li:!0},option:{option:!0,optgroup:!0},optgroup:{optgroup:!0},p:{address:!0,article:!0,aside:!0,blockquote:!0,dir:!0,div:!0,dl:!0,fieldset:!0,footer:!0,form:!0,h1:!0,h2:!0,h3:!0,h4:!0,h5:!0,h6:!0,header:!0,hgroup:!0,hr:!0,menu:!0,nav:!0,ol:!0,p:!0,pre:!0,section:!0,table:!0,ul:!0},rp:{rp:!0,rt:!0},rt:{rp:!0,rt:!0},tbody:{tbody:!0,tfoot:!0},td:{td:!0,th:!0},tfoot:{tbody:!0},th:{td:!0,th:!0},thead:{tbody:!0,tfoot:!0},tr:{tr:!0}},doNotIndent:{pre:!0},allowUnquoted:!0,allowMissing:!0,caseFold:!0},n={autoSelfClosers:{},implicitlyClosed:{},contextGrabbers:{},doNotIndent:{},allowUnquoted:!1,allowMissing:!1,allowMissingTagName:!1,caseFold:!1};e.defineMode("xml",function(r,i){var o,a,l=r.indentUnit,s={},c=i.htmlMode?t:n;for(var u in c)s[u]=c[u];for(var u in i)s[u]=i[u];function f(e,t){function n(n){return t.tokenize=n,n(e,t)}var r=e.next();return"<"==r?e.eat("!")?e.eat("[")?e.match("CDATA[")?n(h("atom","]]>")):null:e.match("--")?n(h("comment","--\x3e")):e.match("DOCTYPE",!0,!0)?(e.eatWhile(/[\w\._\-]/),n(function e(t){return function(n,r){for(var i;null!=(i=n.next());){if("<"==i)return r.tokenize=e(t+1),r.tokenize(n,r);if(">"==i){if(1==t){r.tokenize=f;break}return r.tokenize=e(t-1),r.tokenize(n,r)}}return"meta"}}(1))):null:e.eat("?")?(e.eatWhile(/[\w\._\-]/),t.tokenize=h("meta","?>"),"meta"):(o=e.eat("/")?"closeTag":"openTag",t.tokenize=d,"tag bracket"):"&"==r?(e.eat("#")?e.eat("x")?e.eatWhile(/[a-fA-F\d]/)&&e.eat(";"):e.eatWhile(/[\d]/)&&e.eat(";"):e.eatWhile(/[\w\.\-:]/)&&e.eat(";"))?"atom":"error":(e.eatWhile(/[^&<]/),null)}function d(e,t){var n,r,i=e.next();if(">"==i||"/"==i&&e.eat(">"))return t.tokenize=f,o=">"==i?"endTag":"selfcloseTag","tag bracket";if("="==i)return o="equals",null;if("<"==i){t.tokenize=f,t.state=g,t.tagName=t.tagStart=null;var a=t.tokenize(e,t);return a?a+" tag error":"tag error"}return/[\'\"]/.test(i)?(t.tokenize=(n=i,(r=function(e,t){for(;!e.eol();)if(e.next()==n){t.tokenize=d;break}return"string"}).isInAttribute=!0,r),t.stringStartCol=e.column(),t.tokenize(e,t)):(e.match(/^[^\s\u00a0=<>\"\']*[^\s\u00a0=<>\"\'\/]/),"word")}function h(e,t){return function(n,r){for(;!n.eol();){if(n.match(t)){r.tokenize=f;break}n.next()}return e}}function p(e){e.context&&(e.context=e.context.prev)}function m(e,t){for(var n;;){if(!e.context)return;if(n=e.context.tagName,!s.contextGrabbers.hasOwnProperty(n)||!s.contextGrabbers[n].hasOwnProperty(t))return;p(e)}}function g(e,t,n){return"openTag"==e?(n.tagStart=t.column(),v):"closeTag"==e?y:g}function v(e,t,n){return"word"==e?(n.tagName=t.current(),a="tag",w):s.allowMissingTagName&&"endTag"==e?(a="tag bracket",w(e,0,n)):(a="error",v)}function y(e,t,n){if("word"==e){var r=t.current();return n.context&&n.context.tagName!=r&&s.implicitlyClosed.hasOwnProperty(n.context.tagName)&&p(n),n.context&&n.context.tagName==r||!1===s.matchClosing?(a="tag",b):(a="tag error",x)}return s.allowMissingTagName&&"endTag"==e?(a="tag bracket",b(e,0,n)):(a="error",x)}function b(e,t,n){return"endTag"!=e?(a="error",b):(p(n),g)}function x(e,t,n){return a="error",b(e,0,n)}function w(e,t,n){if("word"==e)return a="attribute",k;if("endTag"==e||"selfcloseTag"==e){var r=n.tagName,i=n.tagStart;return n.tagName=n.tagStart=null,"selfcloseTag"==e||s.autoSelfClosers.hasOwnProperty(r)?m(n,r):(m(n,r),n.context=new function(e,t,n){this.prev=e.context,this.tagName=t,this.indent=e.indented,this.startOfLine=n,(s.doNotIndent.hasOwnProperty(t)||e.context&&e.context.noIndent)&&(this.noIndent=!0)}(n,r,i==n.indented)),g}return a="error",w}function k(e,t,n){return"equals"==e?C:(s.allowMissing||(a="error"),w(e,0,n))}function C(e,t,n){return"string"==e?S:"word"==e&&s.allowUnquoted?(a="string",w):(a="error",w(e,0,n))}function S(e,t,n){return"string"==e?S:w(e,0,n)}return f.isInText=!0,{startState:function(e){var t={tokenize:f,state:g,indented:e||0,tagName:null,tagStart:null,context:null};return null!=e&&(t.baseIndent=e),t},token:function(e,t){if(!t.tagName&&e.sol()&&(t.indented=e.indentation()),e.eatSpace())return null;o=null;var n=t.tokenize(e,t);return(n||o)&&"comment"!=n&&(a=null,t.state=t.state(o||n,e,t),a&&(n="error"==a?n+" error":a)),n},indent:function(t,n,r){var i=t.context;if(t.tokenize.isInAttribute)return t.tagStart==t.indented?t.stringStartCol+1:t.indented+l;if(i&&i.noIndent)return e.Pass;if(t.tokenize!=d&&t.tokenize!=f)return r?r.match(/^(\s*)/)[0].length:0;if(t.tagName)return!1!==s.multilineTagIndentPastTag?t.tagStart+t.tagName.length+2:t.tagStart+l*(s.multilineTagIndentFactor||1);if(s.alignCDATA&&/$/,blockCommentStart:"\x3c!--",blockCommentEnd:"--\x3e",configuration:s.htmlMode?"html":"xml",helperType:s.htmlMode?"html":"xml",skipAttribute:function(e){e.state==C&&(e.state=w)}}}),e.defineMIME("text/xml","xml"),e.defineMIME("application/xml","xml"),e.mimeModes.hasOwnProperty("text/html")||e.defineMIME("text/html",{name:"xml",htmlMode:!0})}(n(0))},function(e,t,n){!function(e){"use strict";e.defineMode("javascript",function(t,n){var r,i,o=t.indentUnit,a=n.statementIndent,l=n.jsonld,s=n.json||l,c=n.typescript,u=n.wordCharacters||/[\w$\xa1-\uffff]/,f=function(){function e(e){return{type:e,style:"keyword"}}var t=e("keyword a"),n=e("keyword b"),r=e("keyword c"),i=e("keyword d"),o=e("operator"),a={type:"atom",style:"atom"};return{if:e("if"),while:t,with:t,else:n,do:n,try:n,finally:n,return:i,break:i,continue:i,new:e("new"),delete:r,void:r,throw:r,debugger:e("debugger"),var:e("var"),const:e("var"),let:e("var"),function:e("function"),catch:e("catch"),for:e("for"),switch:e("switch"),case:e("case"),default:e("default"),in:o,typeof:o,instanceof:o,true:a,false:a,null:a,undefined:a,NaN:a,Infinity:a,this:e("this"),class:e("class"),super:e("atom"),yield:r,export:e("export"),import:e("import"),extends:r,await:r}}(),d=/[+\-*&%=<>!?|~^@]/,h=/^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/;function p(e,t,n){return r=e,i=n,t}function m(e,t){var n,r=e.next();if('"'==r||"'"==r)return t.tokenize=(n=r,function(e,t){var r,i=!1;if(l&&"@"==e.peek()&&e.match(h))return t.tokenize=m,p("jsonld-keyword","meta");for(;null!=(r=e.next())&&(r!=n||i);)i=!i&&"\\"==r;return i||(t.tokenize=m),p("string","string")}),t.tokenize(e,t);if("."==r&&e.match(/^\d+(?:[eE][+\-]?\d+)?/))return p("number","number");if("."==r&&e.match(".."))return p("spread","meta");if(/[\[\]{}\(\),;\:\.]/.test(r))return p(r);if("="==r&&e.eat(">"))return p("=>","operator");if("0"==r&&e.match(/^(?:x[\da-f]+|o[0-7]+|b[01]+)n?/i))return p("number","number");if(/\d/.test(r))return e.match(/^\d*(?:n|(?:\.\d*)?(?:[eE][+\-]?\d+)?)?/),p("number","number");if("/"==r)return e.eat("*")?(t.tokenize=g,g(e,t)):e.eat("/")?(e.skipToEnd(),p("comment","comment")):qe(e,t,1)?(function(e){for(var t,n=!1,r=!1;null!=(t=e.next());){if(!n){if("/"==t&&!r)return;"["==t?r=!0:r&&"]"==t&&(r=!1)}n=!n&&"\\"==t}}(e),e.match(/^\b(([gimyus])(?![gimyus]*\2))+\b/),p("regexp","string-2")):(e.eat("="),p("operator","operator",e.current()));if("`"==r)return t.tokenize=v,v(e,t);if("#"==r)return e.skipToEnd(),p("error","error");if(d.test(r))return">"==r&&t.lexical&&">"==t.lexical.type||(e.eat("=")?"!"!=r&&"="!=r||e.eat("="):/[<>*+\-]/.test(r)&&(e.eat(r),">"==r&&e.eat(r))),p("operator","operator",e.current());if(u.test(r)){e.eatWhile(u);var i=e.current();if("."!=t.lastType){if(f.propertyIsEnumerable(i)){var o=f[i];return p(o.type,o.style,i)}if("async"==i&&e.match(/^(\s|\/\*.*?\*\/)*[\[\(\w]/,!1))return p("async","keyword",i)}return p("variable","variable",i)}}function g(e,t){for(var n,r=!1;n=e.next();){if("/"==n&&r){t.tokenize=m;break}r="*"==n}return p("comment","comment")}function v(e,t){for(var n,r=!1;null!=(n=e.next());){if(!r&&("`"==n||"$"==n&&e.eat("{"))){t.tokenize=m;break}r=!r&&"\\"==n}return p("quasi","string-2",e.current())}var y="([{}])";function b(e,t){t.fatArrowAt&&(t.fatArrowAt=null);var n=e.string.indexOf("=>",e.start);if(!(n<0)){if(c){var r=/:\s*(?:\w+(?:<[^>]*>|\[\])?|\{[^}]*\})\s*$/.exec(e.string.slice(e.start,n));r&&(n=r.index)}for(var i=0,o=!1,a=n-1;a>=0;--a){var l=e.string.charAt(a),s=y.indexOf(l);if(s>=0&&s<3){if(!i){++a;break}if(0==--i){"("==l&&(o=!0);break}}else if(s>=3&&s<6)++i;else if(u.test(l))o=!0;else{if(/["'\/]/.test(l))return;if(o&&!i){++a;break}}}o&&!i&&(t.fatArrowAt=a)}}var x={atom:!0,number:!0,variable:!0,string:!0,regexp:!0,this:!0,"jsonld-keyword":!0};function w(e,t,n,r,i,o){this.indented=e,this.column=t,this.type=n,this.prev=i,this.info=o,null!=r&&(this.align=r)}function k(e,t){for(var n=e.localVars;n;n=n.next)if(n.name==t)return!0;for(var r=e.context;r;r=r.prev)for(var n=r.vars;n;n=n.next)if(n.name==t)return!0}var C={state:null,column:null,marked:null,cc:null};function S(){for(var e=arguments.length-1;e>=0;e--)C.cc.push(arguments[e])}function L(){return S.apply(null,arguments),!0}function M(e,t){for(var n=t;n;n=n.next)if(n.name==e)return!0;return!1}function T(e){var t=C.state;if(C.marked="def",t.context)if("var"==t.lexical.info&&t.context&&t.context.block){var r=function e(t,n){if(n){if(n.block){var r=e(t,n.prev);return r?r==n.prev?n:new O(r,n.vars,!0):null}return M(t,n.vars)?n:new O(n.prev,new E(t,n.vars),!1)}return null}(e,t.context);if(null!=r)return void(t.context=r)}else if(!M(e,t.localVars))return void(t.localVars=new E(e,t.localVars));n.globalVars&&!M(e,t.globalVars)&&(t.globalVars=new E(e,t.globalVars))}function A(e){return"public"==e||"private"==e||"protected"==e||"abstract"==e||"readonly"==e}function O(e,t,n){this.prev=e,this.vars=t,this.block=n}function E(e,t){this.name=e,this.next=t}var N=new E("this",new E("arguments",null));function P(){C.state.context=new O(C.state.context,C.state.localVars,!1),C.state.localVars=N}function I(){C.state.context=new O(C.state.context,C.state.localVars,!0),C.state.localVars=null}function R(){C.state.localVars=C.state.context.vars,C.state.context=C.state.context.prev}function B(e,t){var n=function(){var n=C.state,r=n.indented;if("stat"==n.lexical.type)r=n.lexical.indented;else for(var i=n.lexical;i&&")"==i.type&&i.align;i=i.prev)r=i.indented;n.lexical=new w(r,C.stream.column(),e,null,n.lexical,t)};return n.lex=!0,n}function D(){var e=C.state;e.lexical.prev&&(")"==e.lexical.type&&(e.indented=e.lexical.indented),e.lexical=e.lexical.prev)}function F(e){return function t(n){return n==e?L():";"==e?S():L(t)}}function W(e,t){return"var"==e?L(B("vardef",t),ye,F(";"),D):"keyword a"==e?L(B("form"),K,W,D):"keyword b"==e?L(B("form"),W,D):"keyword d"==e?C.stream.match(/^\s*$/,!1)?L():L(B("stat"),U,F(";"),D):"debugger"==e?L(F(";")):"{"==e?L(B("}"),I,ae,D,R):";"==e?L():"if"==e?("else"==C.state.lexical.info&&C.state.cc[C.state.cc.length-1]==D&&C.state.cc.pop()(),L(B("form"),K,W,D,Ce)):"function"==e?L(Oe):"for"==e?L(B("form"),Se,W,D):"class"==e||c&&"interface"==t?(C.marked="keyword",L(B("form"),Pe,D)):"variable"==e?c&&"declare"==t?(C.marked="keyword",L(W)):c&&("module"==t||"enum"==t||"type"==t)&&C.stream.match(/^\s*\w/,!1)?(C.marked="keyword","enum"==t?L(Ue):"type"==t?L(ue,F("operator"),ue,F(";")):L(B("form"),be,F("{"),B("}"),ae,D,D)):c&&"namespace"==t?(C.marked="keyword",L(B("form"),_,ae,D)):c&&"abstract"==t?(C.marked="keyword",L(W)):L(B("stat"),Q):"switch"==e?L(B("form"),K,F("{"),B("}","switch"),I,ae,D,D,R):"case"==e?L(_,F(":")):"default"==e?L(F(":")):"catch"==e?L(B("form"),P,z,W,D,R):"export"==e?L(B("stat"),De,D):"import"==e?L(B("stat"),We,D):"async"==e?L(W):"@"==t?L(_,W):S(B("stat"),_,F(";"),D)}function z(e){if("("==e)return L(Ee,F(")"))}function _(e,t){return j(e,t,!1)}function H(e,t){return j(e,t,!0)}function K(e){return"("!=e?S():L(B(")"),_,F(")"),D)}function j(e,t,n){if(C.state.fatArrowAt==C.stream.start){var r=n?Y:X;if("("==e)return L(P,B(")"),ie(Ee,")"),D,F("=>"),r,R);if("variable"==e)return S(P,be,F("=>"),r,R)}var i=n?q:V;return x.hasOwnProperty(e)?L(i):"function"==e?L(Oe,i):"class"==e||c&&"interface"==t?(C.marked="keyword",L(B("form"),Ne,D)):"keyword c"==e||"async"==e?L(n?H:_):"("==e?L(B(")"),U,F(")"),D,i):"operator"==e||"spread"==e?L(n?H:_):"["==e?L(B("]"),je,D,i):"{"==e?oe(te,"}",null,i):"quasi"==e?S($,i):"new"==e?L(function(e){return function(t){return"."==t?L(e?J:Z):"variable"==t&&c?L(me,e?q:V):S(e?H:_)}}(n)):"import"==e?L(_):L()}function U(e){return e.match(/[;\}\)\],]/)?S():S(_)}function V(e,t){return","==e?L(_):q(e,t,!1)}function q(e,t,n){var r=0==n?V:q,i=0==n?_:H;return"=>"==e?L(P,n?Y:X,R):"operator"==e?/\+\+|--/.test(t)||c&&"!"==t?L(r):c&&"<"==t&&C.stream.match(/^([^>]|<.*?>)*>\s*\(/,!1)?L(B(">"),ie(ue,">"),D,r):"?"==t?L(_,F(":"),i):L(i):"quasi"==e?S($,r):";"!=e?"("==e?oe(H,")","call",r):"."==e?L(ee,r):"["==e?L(B("]"),U,F("]"),D,r):c&&"as"==t?(C.marked="keyword",L(ue,r)):"regexp"==e?(C.state.lastType=C.marked="operator",C.stream.backUp(C.stream.pos-C.stream.start-1),L(i)):void 0:void 0}function $(e,t){return"quasi"!=e?S():"${"!=t.slice(t.length-2)?L($):L(_,G)}function G(e){if("}"==e)return C.marked="string-2",C.state.tokenize=v,L($)}function X(e){return b(C.stream,C.state),S("{"==e?W:_)}function Y(e){return b(C.stream,C.state),S("{"==e?W:H)}function Z(e,t){if("target"==t)return C.marked="keyword",L(V)}function J(e,t){if("target"==t)return C.marked="keyword",L(q)}function Q(e){return":"==e?L(D,W):S(V,F(";"),D)}function ee(e){if("variable"==e)return C.marked="property",L()}function te(e,t){if("async"==e)return C.marked="property",L(te);if("variable"==e||"keyword"==C.style){return C.marked="property","get"==t||"set"==t?L(ne):(c&&C.state.fatArrowAt==C.stream.start&&(n=C.stream.match(/^\s*:\s*/,!1))&&(C.state.fatArrowAt=C.stream.pos+n[0].length),L(re));var n}else{if("number"==e||"string"==e)return C.marked=l?"property":C.style+" property",L(re);if("jsonld-keyword"==e)return L(re);if(c&&A(t))return C.marked="keyword",L(te);if("["==e)return L(_,le,F("]"),re);if("spread"==e)return L(H,re);if("*"==t)return C.marked="keyword",L(te);if(":"==e)return S(re)}}function ne(e){return"variable"!=e?S(re):(C.marked="property",L(Oe))}function re(e){return":"==e?L(H):"("==e?S(Oe):void 0}function ie(e,t,n){function r(i,o){if(n?n.indexOf(i)>-1:","==i){var a=C.state.lexical;return"call"==a.info&&(a.pos=(a.pos||0)+1),L(function(n,r){return n==t||r==t?S():S(e)},r)}return i==t||o==t?L():L(F(t))}return function(n,i){return n==t||i==t?L():S(e,r)}}function oe(e,t,n){for(var r=3;r"),ue):void 0}function fe(e){if("=>"==e)return L(ue)}function de(e,t){return"variable"==e||"keyword"==C.style?(C.marked="property",L(de)):"?"==t?L(de):":"==e?L(ue):"["==e?L(_,le,F("]"),de):void 0}function he(e,t){return"variable"==e&&C.stream.match(/^\s*[?:]/,!1)||"?"==t?L(he):":"==e?L(ue):S(ue)}function pe(e,t){return"<"==t?L(B(">"),ie(ue,">"),D,pe):"|"==t||"."==e||"&"==t?L(ue):"["==e?L(F("]"),pe):"extends"==t||"implements"==t?(C.marked="keyword",L(ue)):void 0}function me(e,t){if("<"==t)return L(B(">"),ie(ue,">"),D,pe)}function ge(){return S(ue,ve)}function ve(e,t){if("="==t)return L(ue)}function ye(e,t){return"enum"==t?(C.marked="keyword",L(Ue)):S(be,le,we,ke)}function be(e,t){return c&&A(t)?(C.marked="keyword",L(be)):"variable"==e?(T(t),L()):"spread"==e?L(be):"["==e?oe(be,"]"):"{"==e?oe(xe,"}"):void 0}function xe(e,t){return"variable"!=e||C.stream.match(/^\s*:/,!1)?("variable"==e&&(C.marked="property"),"spread"==e?L(be):"}"==e?S():L(F(":"),be,we)):(T(t),L(we))}function we(e,t){if("="==t)return L(H)}function ke(e){if(","==e)return L(ye)}function Ce(e,t){if("keyword b"==e&&"else"==t)return L(B("form","else"),W,D)}function Se(e,t){return"await"==t?L(Se):"("==e?L(B(")"),Le,F(")"),D):void 0}function Le(e){return"var"==e?L(ye,F(";"),Te):";"==e?L(Te):"variable"==e?L(Me):S(_,F(";"),Te)}function Me(e,t){return"in"==t||"of"==t?(C.marked="keyword",L(_)):L(V,Te)}function Te(e,t){return";"==e?L(Ae):"in"==t||"of"==t?(C.marked="keyword",L(_)):S(_,F(";"),Ae)}function Ae(e){")"!=e&&L(_)}function Oe(e,t){return"*"==t?(C.marked="keyword",L(Oe)):"variable"==e?(T(t),L(Oe)):"("==e?L(P,B(")"),ie(Ee,")"),D,se,W,R):c&&"<"==t?L(B(">"),ie(ge,">"),D,Oe):void 0}function Ee(e,t){return"@"==t&&L(_,Ee),"spread"==e?L(Ee):c&&A(t)?(C.marked="keyword",L(Ee)):S(be,le,we)}function Ne(e,t){return"variable"==e?Pe(e,t):Ie(e,t)}function Pe(e,t){if("variable"==e)return T(t),L(Ie)}function Ie(e,t){return"<"==t?L(B(">"),ie(ge,">"),D,Ie):"extends"==t||"implements"==t||c&&","==e?("implements"==t&&(C.marked="keyword"),L(c?ue:_,Ie)):"{"==e?L(B("}"),Re,D):void 0}function Re(e,t){return"async"==e||"variable"==e&&("static"==t||"get"==t||"set"==t||c&&A(t))&&C.stream.match(/^\s+[\w$\xa1-\uffff]/,!1)?(C.marked="keyword",L(Re)):"variable"==e||"keyword"==C.style?(C.marked="property",L(c?Be:Oe,Re)):"["==e?L(_,le,F("]"),c?Be:Oe,Re):"*"==t?(C.marked="keyword",L(Re)):";"==e?L(Re):"}"==e?L():"@"==t?L(_,Re):void 0}function Be(e,t){return"?"==t?L(Be):":"==e?L(ue,we):"="==t?L(H):S(Oe)}function De(e,t){return"*"==t?(C.marked="keyword",L(Ke,F(";"))):"default"==t?(C.marked="keyword",L(_,F(";"))):"{"==e?L(ie(Fe,"}"),Ke,F(";")):S(W)}function Fe(e,t){return"as"==t?(C.marked="keyword",L(F("variable"))):"variable"==e?S(H,Fe):void 0}function We(e){return"string"==e?L():"("==e?S(_):S(ze,_e,Ke)}function ze(e,t){return"{"==e?oe(ze,"}"):("variable"==e&&T(t),"*"==t&&(C.marked="keyword"),L(He))}function _e(e){if(","==e)return L(ze,_e)}function He(e,t){if("as"==t)return C.marked="keyword",L(ze)}function Ke(e,t){if("from"==t)return C.marked="keyword",L(_)}function je(e){return"]"==e?L():S(ie(H,"]"))}function Ue(){return S(B("form"),be,F("{"),B("}"),ie(Ve,"}"),D,D)}function Ve(){return S(be,we)}function qe(e,t,n){return t.tokenize==m&&/^(?:operator|sof|keyword [bcd]|case|new|export|default|spread|[\[{}\(,;:]|=>)$/.test(t.lastType)||"quasi"==t.lastType&&/\{\s*$/.test(e.string.slice(0,e.pos-(n||0)))}return R.lex=!0,D.lex=!0,{startState:function(e){var t={tokenize:m,lastType:"sof",cc:[],lexical:new w((e||0)-o,0,"block",!1),localVars:n.localVars,context:n.localVars&&new O(null,null,!1),indented:e||0};return n.globalVars&&"object"==typeof n.globalVars&&(t.globalVars=n.globalVars),t},token:function(e,t){if(e.sol()&&(t.lexical.hasOwnProperty("align")||(t.lexical.align=!1),t.indented=e.indentation(),b(e,t)),t.tokenize!=g&&e.eatSpace())return null;var n=t.tokenize(e,t);return"comment"==r?n:(t.lastType="operator"!=r||"++"!=i&&"--"!=i?r:"incdec",function(e,t,n,r,i){var o=e.cc;for(C.state=e,C.stream=i,C.marked=null,C.cc=o,C.style=t,e.lexical.hasOwnProperty("align")||(e.lexical.align=!0);;){var a=o.length?o.pop():s?_:W;if(a(n,r)){for(;o.length&&o[o.length-1].lex;)o.pop()();return C.marked?C.marked:"variable"==n&&k(e,r)?"variable-2":t}}}(t,n,r,i,e))},indent:function(t,r){if(t.tokenize==g)return e.Pass;if(t.tokenize!=m)return 0;var i,l=r&&r.charAt(0),s=t.lexical;if(!/^\s*else\b/.test(r))for(var c=t.cc.length-1;c>=0;--c){var u=t.cc[c];if(u==D)s=s.prev;else if(u!=Ce)break}for(;("stat"==s.type||"form"==s.type)&&("}"==l||(i=t.cc[t.cc.length-1])&&(i==V||i==q)&&!/^[,\.=+\-*:?[\(]/.test(r));)s=s.prev;a&&")"==s.type&&"stat"==s.prev.type&&(s=s.prev);var f=s.type,h=l==f;return"vardef"==f?s.indented+("operator"==t.lastType||","==t.lastType?s.info.length+1:0):"form"==f&&"{"==l?s.indented:"form"==f?s.indented+o:"stat"==f?s.indented+(function(e,t){return"operator"==e.lastType||","==e.lastType||d.test(t.charAt(0))||/[,.]/.test(t.charAt(0))}(t,r)?a||o:0):"switch"!=s.info||h||0==n.doubleIndentSwitch?s.align?s.column+(h?0:1):s.indented+(h?0:o):s.indented+(/^(?:case|default)\b/.test(r)?o:2*o)},electricInput:/^\s*(?:case .*?:|default:|\{|\})$/,blockCommentStart:s?null:"/*",blockCommentEnd:s?null:"*/",blockCommentContinue:s?null:" * ",lineComment:s?null:"//",fold:"brace",closeBrackets:"()[]{}''\"\"``",helperType:s?"json":"javascript",jsonldMode:l,jsonMode:s,expressionAllowed:qe,skipExpression:function(e){var t=e.cc[e.cc.length-1];t!=_&&t!=H||e.cc.pop()}}}),e.registerHelper("wordChars","javascript",/[\w$]/),e.defineMIME("text/javascript","javascript"),e.defineMIME("text/ecmascript","javascript"),e.defineMIME("application/javascript","javascript"),e.defineMIME("application/x-javascript","javascript"),e.defineMIME("application/ecmascript","javascript"),e.defineMIME("application/json",{name:"javascript",json:!0}),e.defineMIME("application/x-json",{name:"javascript",json:!0}),e.defineMIME("application/ld+json",{name:"javascript",jsonld:!0}),e.defineMIME("text/typescript",{name:"javascript",typescript:!0}),e.defineMIME("application/typescript",{name:"javascript",typescript:!0})}(n(0))},function(e,t,n){!function(e){var t=/MSIE \d/.test(navigator.userAgent)&&(null==document.documentMode||document.documentMode<8),n=e.Pos,r={"(":")>",")":"(<","[":"]>","]":"[<","{":"}>","}":"{<"};function i(e,t,i){var a=e.getLineHandle(t.line),l=t.ch-1,s=i&&i.afterCursor;null==s&&(s=/(^| )cm-fat-cursor($| )/.test(e.getWrapperElement().className));var c=!s&&l>=0&&r[a.text.charAt(l)]||r[a.text.charAt(++l)];if(!c)return null;var u=">"==c.charAt(1)?1:-1;if(i&&i.strict&&u>0!=(l==t.ch))return null;var f=e.getTokenTypeAt(n(t.line,l+1)),d=o(e,n(t.line,l+(u>0?1:0)),u,f||null,i);return null==d?null:{from:n(t.line,l),to:d&&d.pos,match:d&&d.ch==c.charAt(0),forward:u>0}}function o(e,t,i,o,a){for(var l=a&&a.maxScanLineLength||1e4,s=a&&a.maxScanLines||1e3,c=[],u=a&&a.bracketRegex?a.bracketRegex:/[(){}[\]]/,f=i>0?Math.min(t.line+s,e.lastLine()+1):Math.max(e.firstLine()-1,t.line-s),d=t.line;d!=f;d+=i){var h=e.getLine(d);if(h){var p=i>0?0:h.length-1,m=i>0?h.length:-1;if(!(h.length>l))for(d==t.line&&(p=t.ch-(i<0?1:0));p!=m;p+=i){var g=h.charAt(p);if(u.test(g)&&(void 0===o||e.getTokenTypeAt(n(d,p+1))==o)){var v=r[g];if(">"==v.charAt(1)==i>0)c.push(g);else{if(!c.length)return{pos:n(d,p),ch:g};c.pop()}}}}}return d-i!=(i>0?e.lastLine():e.firstLine())&&null}function a(e,r,o){for(var a=e.state.matchBrackets.maxHighlightLineLength||1e3,l=[],s=e.listSelections(),c=0;ct.firstLine();)n=e.Pos(n.line-1,0),c=s(!1);if(c&&!c.cleared&&"unfold"!==o){var u=function(e,t){var n=r(e,t,"widget");if("string"==typeof n){var i=document.createTextNode(n);(n=document.createElement("span")).appendChild(i),n.className="CodeMirror-foldmarker"}else n&&(n=n.cloneNode(!0));return n}(t,i);e.on(u,"mousedown",function(t){f.clear(),e.e_preventDefault(t)});var f=t.markText(c.from,c.to,{replacedWith:u,clearOnEnter:r(t,i,"clearOnEnter"),__isFold:!0});f.on("clear",function(n,r){e.signal(t,"unfold",t,n,r)}),e.signal(t,"fold",t,c.from,c.to)}}e.newFoldFunction=function(e,n){return function(r,i){t(r,i,{rangeFinder:e,widget:n})}},e.defineExtension("foldCode",function(e,n,r){t(this,e,n,r)}),e.defineExtension("isFolded",function(e){for(var t=this.findMarksAt(e),n=0;n0;i--)n.context=n.context.prev;return T(e,t,n)}function O(e){var t=e.current().toLowerCase();o=v.hasOwnProperty(t)?"atom":g.hasOwnProperty(t)?"keyword":"variable"}var E={top:function(e,t,n){if("{"==e)return L(n,t,"block");if("}"==e&&n.context.prev)return M(n);if(x&&/@component/i.test(e))return L(n,t,"atComponentBlock");if(/^@(-moz-)?document$/i.test(e))return L(n,t,"documentTypes");if(/^@(media|supports|(-moz-)?document|import)$/i.test(e))return L(n,t,"atBlock");if(/^@(font-face|counter-style)/i.test(e))return n.stateArg=e,"restricted_atBlock_before";if(/^@(-(moz|ms|o|webkit)-)?keyframes$/i.test(e))return"keyframes";if(e&&"@"==e.charAt(0))return L(n,t,"at");if("hash"==e)o="builtin";else if("word"==e)o="tag";else{if("variable-definition"==e)return"maybeprop";if("interpolation"==e)return L(n,t,"interpolation");if(":"==e)return"pseudo";if(y&&"("==e)return L(n,t,"parens")}return n.context.type},block:function(e,t,n){if("word"==e){var r=t.current().toLowerCase();return d.hasOwnProperty(r)?(o="property","maybeprop"):h.hasOwnProperty(r)?(o="string-2","maybeprop"):y?(o=t.match(/^\s*:(?:\s|$)/,!1)?"property":"tag","block"):(o+=" error","maybeprop")}return"meta"==e?"block":y||"hash"!=e&&"qualifier"!=e?E.top(e,t,n):(o="error","block")},maybeprop:function(e,t,n){return":"==e?L(n,t,"prop"):T(e,t,n)},prop:function(e,t,n){if(";"==e)return M(n);if("{"==e&&y)return L(n,t,"propBlock");if("}"==e||"{"==e)return A(e,t,n);if("("==e)return L(n,t,"parens");if("hash"!=e||/^#([0-9a-fA-f]{3,4}|[0-9a-fA-f]{6}|[0-9a-fA-f]{8})$/.test(t.current())){if("word"==e)O(t);else if("interpolation"==e)return L(n,t,"interpolation")}else o+=" error";return"prop"},propBlock:function(e,t,n){return"}"==e?M(n):"word"==e?(o="property","maybeprop"):n.context.type},parens:function(e,t,n){return"{"==e||"}"==e?A(e,t,n):")"==e?M(n):"("==e?L(n,t,"parens"):"interpolation"==e?L(n,t,"interpolation"):("word"==e&&O(t),"parens")},pseudo:function(e,t,n){return"meta"==e?"pseudo":"word"==e?(o="variable-3",n.context.type):T(e,t,n)},documentTypes:function(e,t,n){return"word"==e&&s.hasOwnProperty(t.current())?(o="tag",n.context.type):E.atBlock(e,t,n)},atBlock:function(e,t,n){if("("==e)return L(n,t,"atBlock_parens");if("}"==e||";"==e)return A(e,t,n);if("{"==e)return M(n)&&L(n,t,y?"block":"top");if("interpolation"==e)return L(n,t,"interpolation");if("word"==e){var r=t.current().toLowerCase();o="only"==r||"not"==r||"and"==r||"or"==r?"keyword":c.hasOwnProperty(r)?"attribute":u.hasOwnProperty(r)?"property":f.hasOwnProperty(r)?"keyword":d.hasOwnProperty(r)?"property":h.hasOwnProperty(r)?"string-2":v.hasOwnProperty(r)?"atom":g.hasOwnProperty(r)?"keyword":"error"}return n.context.type},atComponentBlock:function(e,t,n){return"}"==e?A(e,t,n):"{"==e?M(n)&&L(n,t,y?"block":"top",!1):("word"==e&&(o="error"),n.context.type)},atBlock_parens:function(e,t,n){return")"==e?M(n):"{"==e||"}"==e?A(e,t,n,2):E.atBlock(e,t,n)},restricted_atBlock_before:function(e,t,n){return"{"==e?L(n,t,"restricted_atBlock"):"word"==e&&"@counter-style"==n.stateArg?(o="variable","restricted_atBlock_before"):T(e,t,n)},restricted_atBlock:function(e,t,n){return"}"==e?(n.stateArg=null,M(n)):"word"==e?(o="@font-face"==n.stateArg&&!p.hasOwnProperty(t.current().toLowerCase())||"@counter-style"==n.stateArg&&!m.hasOwnProperty(t.current().toLowerCase())?"error":"property","maybeprop"):"restricted_atBlock"},keyframes:function(e,t,n){return"word"==e?(o="variable","keyframes"):"{"==e?L(n,t,"top"):T(e,t,n)},at:function(e,t,n){return";"==e?M(n):"{"==e||"}"==e?A(e,t,n):("word"==e?o="tag":"hash"==e&&(o="builtin"),"at")},interpolation:function(e,t,n){return"}"==e?M(n):"{"==e||";"==e?A(e,t,n):("word"==e?o="variable":"variable"!=e&&"("!=e&&")"!=e&&(o="error"),"interpolation")}};return{startState:function(e){return{tokenize:null,state:r?"block":"top",stateArg:null,context:new S(r?"block":"top",e||0,null)}},token:function(e,t){if(!t.tokenize&&e.eatSpace())return null;var n=(t.tokenize||function(e,t){var n=e.next();if(l[n]){var r=l[n](e,t);if(!1!==r)return r}return"@"==n?(e.eatWhile(/[\w\\\-]/),w("def",e.current())):"="==n||("~"==n||"|"==n)&&e.eat("=")?w(null,"compare"):'"'==n||"'"==n?(t.tokenize=k(n),t.tokenize(e,t)):"#"==n?(e.eatWhile(/[\w\\\-]/),w("atom","hash")):"!"==n?(e.match(/^\s*\w*/),w("keyword","important")):/\d/.test(n)||"."==n&&e.eat(/\d/)?(e.eatWhile(/[\w.%]/),w("number","unit")):"-"!==n?/[,+>*\/]/.test(n)?w(null,"select-op"):"."==n&&e.match(/^-?[_a-z][_a-z0-9-]*/i)?w("qualifier","qualifier"):/[:;{}\[\]\(\)]/.test(n)?w(null,n):("u"==n||"U"==n)&&e.match(/rl(-prefix)?\(/i)||("d"==n||"D"==n)&&e.match("omain(",!0,!0)||("r"==n||"R"==n)&&e.match("egexp(",!0,!0)?(e.backUp(1),t.tokenize=C,w("property","word")):/[\w\\\-]/.test(n)?(e.eatWhile(/[\w\\\-]/),w("property","word")):w(null,null):/[\d.]/.test(e.peek())?(e.eatWhile(/[\w.%]/),w("number","unit")):e.match(/^-[\w\\\-]+/)?(e.eatWhile(/[\w\\\-]/),e.match(/^\s*:/,!1)?w("variable-2","variable-definition"):w("variable-2","variable")):e.match(/^\w+-/)?w("meta","meta"):void 0})(e,t);return n&&"object"==typeof n&&(i=n[1],n=n[0]),o=n,"comment"!=i&&(t.state=E[t.state](i,e,t)),o},indent:function(e,t){var n=e.context,r=t&&t.charAt(0),i=n.indent;return"prop"!=n.type||"}"!=r&&")"!=r||(n=n.prev),n.prev&&("}"!=r||"block"!=n.type&&"top"!=n.type&&"interpolation"!=n.type&&"restricted_atBlock"!=n.type?(")"!=r||"parens"!=n.type&&"atBlock_parens"!=n.type)&&("{"!=r||"at"!=n.type&&"atBlock"!=n.type)||(i=Math.max(0,n.indent-a)):(n=n.prev,i=n.indent)),i},electricChars:"}",blockCommentStart:"/*",blockCommentEnd:"*/",blockCommentContinue:" * ",lineComment:b,fold:"brace"}});var n=["domain","regexp","url","url-prefix"],r=t(n),i=["all","aural","braille","handheld","print","projection","screen","tty","tv","embossed"],o=t(i),a=["width","min-width","max-width","height","min-height","max-height","device-width","min-device-width","max-device-width","device-height","min-device-height","max-device-height","aspect-ratio","min-aspect-ratio","max-aspect-ratio","device-aspect-ratio","min-device-aspect-ratio","max-device-aspect-ratio","color","min-color","max-color","color-index","min-color-index","max-color-index","monochrome","min-monochrome","max-monochrome","resolution","min-resolution","max-resolution","scan","grid","orientation","device-pixel-ratio","min-device-pixel-ratio","max-device-pixel-ratio","pointer","any-pointer","hover","any-hover"],l=t(a),s=["landscape","portrait","none","coarse","fine","on-demand","hover","interlace","progressive"],c=t(s),u=["align-content","align-items","align-self","alignment-adjust","alignment-baseline","anchor-point","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","appearance","azimuth","backface-visibility","background","background-attachment","background-blend-mode","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","baseline-shift","binding","bleed","bookmark-label","bookmark-level","bookmark-state","bookmark-target","border","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","caret-color","clear","clip","color","color-profile","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","content","counter-increment","counter-reset","crop","cue","cue-after","cue-before","cursor","direction","display","dominant-baseline","drop-initial-after-adjust","drop-initial-after-align","drop-initial-before-adjust","drop-initial-before-align","drop-initial-size","drop-initial-value","elevation","empty-cells","fit","fit-position","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","float-offset","flow-from","flow-into","font","font-feature-settings","font-family","font-kerning","font-language-override","font-size","font-size-adjust","font-stretch","font-style","font-synthesis","font-variant","font-variant-alternates","font-variant-caps","font-variant-east-asian","font-variant-ligatures","font-variant-numeric","font-variant-position","font-weight","grid","grid-area","grid-auto-columns","grid-auto-flow","grid-auto-rows","grid-column","grid-column-end","grid-column-gap","grid-column-start","grid-gap","grid-row","grid-row-end","grid-row-gap","grid-row-start","grid-template","grid-template-areas","grid-template-columns","grid-template-rows","hanging-punctuation","height","hyphens","icon","image-orientation","image-rendering","image-resolution","inline-box-align","justify-content","justify-items","justify-self","left","letter-spacing","line-break","line-height","line-stacking","line-stacking-ruby","line-stacking-shift","line-stacking-strategy","list-style","list-style-image","list-style-position","list-style-type","margin","margin-bottom","margin-left","margin-right","margin-top","marks","marquee-direction","marquee-loop","marquee-play-count","marquee-speed","marquee-style","max-height","max-width","min-height","min-width","move-to","nav-down","nav-index","nav-left","nav-right","nav-up","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-style","overflow-wrap","overflow-x","overflow-y","padding","padding-bottom","padding-left","padding-right","padding-top","page","page-break-after","page-break-before","page-break-inside","page-policy","pause","pause-after","pause-before","perspective","perspective-origin","pitch","pitch-range","place-content","place-items","place-self","play-during","position","presentation-level","punctuation-trim","quotes","region-break-after","region-break-before","region-break-inside","region-fragment","rendering-intent","resize","rest","rest-after","rest-before","richness","right","rotation","rotation-point","ruby-align","ruby-overhang","ruby-position","ruby-span","shape-image-threshold","shape-inside","shape-margin","shape-outside","size","speak","speak-as","speak-header","speak-numeral","speak-punctuation","speech-rate","stress","string-set","tab-size","table-layout","target","target-name","target-new","target-position","text-align","text-align-last","text-decoration","text-decoration-color","text-decoration-line","text-decoration-skip","text-decoration-style","text-emphasis","text-emphasis-color","text-emphasis-position","text-emphasis-style","text-height","text-indent","text-justify","text-outline","text-overflow","text-shadow","text-size-adjust","text-space-collapse","text-transform","text-underline-position","text-wrap","top","transform","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","user-select","vertical-align","visibility","voice-balance","voice-duration","voice-family","voice-pitch","voice-range","voice-rate","voice-stress","voice-volume","volume","white-space","widows","width","will-change","word-break","word-spacing","word-wrap","z-index","clip-path","clip-rule","mask","enable-background","filter","flood-color","flood-opacity","lighting-color","stop-color","stop-opacity","pointer-events","color-interpolation","color-interpolation-filters","color-rendering","fill","fill-opacity","fill-rule","image-rendering","marker","marker-end","marker-mid","marker-start","shape-rendering","stroke","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","text-rendering","baseline-shift","dominant-baseline","glyph-orientation-horizontal","glyph-orientation-vertical","text-anchor","writing-mode"],f=t(u),d=["scrollbar-arrow-color","scrollbar-base-color","scrollbar-dark-shadow-color","scrollbar-face-color","scrollbar-highlight-color","scrollbar-shadow-color","scrollbar-3d-light-color","scrollbar-track-color","shape-inside","searchfield-cancel-button","searchfield-decoration","searchfield-results-button","searchfield-results-decoration","zoom"],h=t(d),p=t(["font-family","src","unicode-range","font-variant","font-feature-settings","font-stretch","font-weight","font-style"]),m=t(["additive-symbols","fallback","negative","pad","prefix","range","speak-as","suffix","symbols","system"]),g=["aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","grey","green","greenyellow","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgreen","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen"],v=t(g),y=["above","absolute","activeborder","additive","activecaption","afar","after-white-space","ahead","alias","all","all-scroll","alphabetic","alternate","always","amharic","amharic-abegede","antialiased","appworkspace","arabic-indic","armenian","asterisks","attr","auto","auto-flow","avoid","avoid-column","avoid-page","avoid-region","background","backwards","baseline","below","bidi-override","binary","bengali","blink","block","block-axis","bold","bolder","border","border-box","both","bottom","break","break-all","break-word","bullets","button","button-bevel","buttonface","buttonhighlight","buttonshadow","buttontext","calc","cambodian","capitalize","caps-lock-indicator","caption","captiontext","caret","cell","center","checkbox","circle","cjk-decimal","cjk-earthly-branch","cjk-heavenly-stem","cjk-ideographic","clear","clip","close-quote","col-resize","collapse","color","color-burn","color-dodge","column","column-reverse","compact","condensed","contain","content","contents","content-box","context-menu","continuous","copy","counter","counters","cover","crop","cross","crosshair","currentcolor","cursive","cyclic","darken","dashed","decimal","decimal-leading-zero","default","default-button","dense","destination-atop","destination-in","destination-out","destination-over","devanagari","difference","disc","discard","disclosure-closed","disclosure-open","document","dot-dash","dot-dot-dash","dotted","double","down","e-resize","ease","ease-in","ease-in-out","ease-out","element","ellipse","ellipsis","embed","end","ethiopic","ethiopic-abegede","ethiopic-abegede-am-et","ethiopic-abegede-gez","ethiopic-abegede-ti-er","ethiopic-abegede-ti-et","ethiopic-halehame-aa-er","ethiopic-halehame-aa-et","ethiopic-halehame-am-et","ethiopic-halehame-gez","ethiopic-halehame-om-et","ethiopic-halehame-sid-et","ethiopic-halehame-so-et","ethiopic-halehame-ti-er","ethiopic-halehame-ti-et","ethiopic-halehame-tig","ethiopic-numeric","ew-resize","exclusion","expanded","extends","extra-condensed","extra-expanded","fantasy","fast","fill","fixed","flat","flex","flex-end","flex-start","footnotes","forwards","from","geometricPrecision","georgian","graytext","grid","groove","gujarati","gurmukhi","hand","hangul","hangul-consonant","hard-light","hebrew","help","hidden","hide","higher","highlight","highlighttext","hiragana","hiragana-iroha","horizontal","hsl","hsla","hue","icon","ignore","inactiveborder","inactivecaption","inactivecaptiontext","infinite","infobackground","infotext","inherit","initial","inline","inline-axis","inline-block","inline-flex","inline-grid","inline-table","inset","inside","intrinsic","invert","italic","japanese-formal","japanese-informal","justify","kannada","katakana","katakana-iroha","keep-all","khmer","korean-hangul-formal","korean-hanja-formal","korean-hanja-informal","landscape","lao","large","larger","left","level","lighter","lighten","line-through","linear","linear-gradient","lines","list-item","listbox","listitem","local","logical","loud","lower","lower-alpha","lower-armenian","lower-greek","lower-hexadecimal","lower-latin","lower-norwegian","lower-roman","lowercase","ltr","luminosity","malayalam","match","matrix","matrix3d","media-controls-background","media-current-time-display","media-fullscreen-button","media-mute-button","media-play-button","media-return-to-realtime-button","media-rewind-button","media-seek-back-button","media-seek-forward-button","media-slider","media-sliderthumb","media-time-remaining-display","media-volume-slider","media-volume-slider-container","media-volume-sliderthumb","medium","menu","menulist","menulist-button","menulist-text","menulist-textfield","menutext","message-box","middle","min-intrinsic","mix","mongolian","monospace","move","multiple","multiply","myanmar","n-resize","narrower","ne-resize","nesw-resize","no-close-quote","no-drop","no-open-quote","no-repeat","none","normal","not-allowed","nowrap","ns-resize","numbers","numeric","nw-resize","nwse-resize","oblique","octal","opacity","open-quote","optimizeLegibility","optimizeSpeed","oriya","oromo","outset","outside","outside-shape","overlay","overline","padding","padding-box","painted","page","paused","persian","perspective","plus-darker","plus-lighter","pointer","polygon","portrait","pre","pre-line","pre-wrap","preserve-3d","progress","push-button","radial-gradient","radio","read-only","read-write","read-write-plaintext-only","rectangle","region","relative","repeat","repeating-linear-gradient","repeating-radial-gradient","repeat-x","repeat-y","reset","reverse","rgb","rgba","ridge","right","rotate","rotate3d","rotateX","rotateY","rotateZ","round","row","row-resize","row-reverse","rtl","run-in","running","s-resize","sans-serif","saturation","scale","scale3d","scaleX","scaleY","scaleZ","screen","scroll","scrollbar","scroll-position","se-resize","searchfield","searchfield-cancel-button","searchfield-decoration","searchfield-results-button","searchfield-results-decoration","self-start","self-end","semi-condensed","semi-expanded","separate","serif","show","sidama","simp-chinese-formal","simp-chinese-informal","single","skew","skewX","skewY","skip-white-space","slide","slider-horizontal","slider-vertical","sliderthumb-horizontal","sliderthumb-vertical","slow","small","small-caps","small-caption","smaller","soft-light","solid","somali","source-atop","source-in","source-out","source-over","space","space-around","space-between","space-evenly","spell-out","square","square-button","start","static","status-bar","stretch","stroke","sub","subpixel-antialiased","super","sw-resize","symbolic","symbols","system-ui","table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row","table-row-group","tamil","telugu","text","text-bottom","text-top","textarea","textfield","thai","thick","thin","threeddarkshadow","threedface","threedhighlight","threedlightshadow","threedshadow","tibetan","tigre","tigrinya-er","tigrinya-er-abegede","tigrinya-et","tigrinya-et-abegede","to","top","trad-chinese-formal","trad-chinese-informal","transform","translate","translate3d","translateX","translateY","translateZ","transparent","ultra-condensed","ultra-expanded","underline","unset","up","upper-alpha","upper-armenian","upper-greek","upper-hexadecimal","upper-latin","upper-norwegian","upper-roman","uppercase","urdu","url","var","vertical","vertical-text","visible","visibleFill","visiblePainted","visibleStroke","visual","w-resize","wait","wave","wider","window","windowframe","windowtext","words","wrap","wrap-reverse","x-large","x-small","xor","xx-large","xx-small"],b=t(y),x=n.concat(i).concat(a).concat(s).concat(u).concat(d).concat(g).concat(y);function w(e,t){for(var n,r=!1;null!=(n=e.next());){if(r&&"/"==n){t.tokenize=null;break}r="*"==n}return["comment","comment"]}e.registerHelper("hintWords","css",x),e.defineMIME("text/css",{documentTypes:r,mediaTypes:o,mediaFeatures:l,mediaValueKeywords:c,propertyKeywords:f,nonStandardPropertyKeywords:h,fontProperties:p,counterDescriptors:m,colorKeywords:v,valueKeywords:b,tokenHooks:{"/":function(e,t){return!!e.eat("*")&&(t.tokenize=w,w(e,t))}},name:"css"}),e.defineMIME("text/x-scss",{mediaTypes:o,mediaFeatures:l,mediaValueKeywords:c,propertyKeywords:f,nonStandardPropertyKeywords:h,colorKeywords:v,valueKeywords:b,fontProperties:p,allowNested:!0,lineComment:"//",tokenHooks:{"/":function(e,t){return e.eat("/")?(e.skipToEnd(),["comment","comment"]):e.eat("*")?(t.tokenize=w,w(e,t)):["operator","operator"]},":":function(e){return!!e.match(/\s*\{/,!1)&&[null,null]},$:function(e){return e.match(/^[\w-]+/),e.match(/^\s*:/,!1)?["variable-2","variable-definition"]:["variable-2","variable"]},"#":function(e){return!!e.eat("{")&&[null,"interpolation"]}},name:"css",helperType:"scss"}),e.defineMIME("text/x-less",{mediaTypes:o,mediaFeatures:l,mediaValueKeywords:c,propertyKeywords:f,nonStandardPropertyKeywords:h,colorKeywords:v,valueKeywords:b,fontProperties:p,allowNested:!0,lineComment:"//",tokenHooks:{"/":function(e,t){return e.eat("/")?(e.skipToEnd(),["comment","comment"]):e.eat("*")?(t.tokenize=w,w(e,t)):["operator","operator"]},"@":function(e){return e.eat("{")?[null,"interpolation"]:!e.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/i,!1)&&(e.eatWhile(/[\w\\\-]/),e.match(/^\s*:/,!1)?["variable-2","variable-definition"]:["variable-2","variable"])},"&":function(){return["atom","atom"]}},name:"css",helperType:"less"}),e.defineMIME("text/x-gss",{documentTypes:r,mediaTypes:o,mediaFeatures:l,propertyKeywords:f,nonStandardPropertyKeywords:h,fontProperties:p,counterDescriptors:m,colorKeywords:v,valueKeywords:b,supportsAtComponent:!0,tokenHooks:{"/":function(e,t){return!!e.eat("*")&&(t.tokenize=w,w(e,t))}},name:"css",helperType:"gss"})}(n(0))},function(e,t,n){!function(e){"use strict";e.runMode=function(t,n,r,i){var o=e.getMode(e.defaults,n),a=/MSIE \d/.test(navigator.userAgent),l=a&&(null==document.documentMode||document.documentMode<9);if(r.appendChild){var s=i&&i.tabSize||e.defaults.tabSize,c=r,u=0;c.innerHTML="",r=function(e,t){if("\n"==e)return c.appendChild(document.createTextNode(l?"\r":e)),void(u=0);for(var n="",r=0;;){var i=e.indexOf("\t",r);if(-1==i){n+=e.slice(r),u+=e.length-r;break}u+=i-r,n+=e.slice(r,i);var o=s-u%s;u+=o;for(var a=0;a=s&&(o=r(a.indicatorOpen))}e.setGutterMarker(i,a.gutter,o),++l})}function o(e){var t=e.getViewport(),n=e.state.foldGutter;n&&(e.operation(function(){i(e,t.from,t.to)}),n.from=t.from,n.to=t.to)}function a(e,r,i){var o=e.state.foldGutter;if(o){var a=o.options;if(i==a.gutter){var l=n(e,r);l?l.clear():e.foldCode(t(r,0),a.rangeFinder)}}}function l(e){var t=e.state.foldGutter;if(t){var n=t.options;t.from=t.to=0,clearTimeout(t.changeUpdate),t.changeUpdate=setTimeout(function(){o(e)},n.foldOnChangeTimeSpan||600)}}function s(e){var t=e.state.foldGutter;if(t){var n=t.options;clearTimeout(t.changeUpdate),t.changeUpdate=setTimeout(function(){var n=e.getViewport();t.from==t.to||n.from-t.to>20||t.from-n.to>20?o(e):e.operation(function(){n.fromt.to&&(i(e,t.to,n.to),t.to=n.to)})},n.updateViewportTimeSpan||400)}}function c(e,t){var n=e.state.foldGutter;if(n){var r=t.line;r>=n.from&&r=e.max))return e.ch=0,e.text=e.cm.getLine(++e.line),!0}function s(e){if(!(e.line<=e.min))return e.text=e.cm.getLine(--e.line),e.ch=e.text.length,!0}function c(e){for(;;){var t=e.text.indexOf(">",e.ch);if(-1==t){if(l(e))continue;return}if(a(e,t+1)){var n=e.text.lastIndexOf("/",t),r=n>-1&&!/\S/.test(e.text.slice(n+1,t));return e.ch=t+1,r?"selfClose":"regular"}e.ch=t+1}}function u(e){for(;;){var t=e.ch?e.text.lastIndexOf("<",e.ch-1):-1;if(-1==t){if(s(e))continue;return}if(a(e,t+1)){i.lastIndex=t,e.ch=t;var n=i.exec(e.text);if(n&&n.index==t)return n}else e.ch=t}}function f(e){for(;;){i.lastIndex=e.ch;var t=i.exec(e.text);if(!t){if(l(e))continue;return}if(a(e,t.index+1))return e.ch=t.index+t[0].length,t;e.ch=t.index+1}}function d(e){for(;;){var t=e.ch?e.text.lastIndexOf(">",e.ch-1):-1;if(-1==t){if(s(e))continue;return}if(a(e,t+1)){var n=e.text.lastIndexOf("/",t),r=n>-1&&!/\S/.test(e.text.slice(n+1,t));return e.ch=t+1,r?"selfClose":"regular"}e.ch=t}}function h(e,n){for(var r=[];;){var i,o=f(e),a=e.line,l=e.ch-(o?o[0].length:0);if(!o||!(i=c(e)))return;if("selfClose"!=i)if(o[1]){for(var s=r.length-1;s>=0;--s)if(r[s]==o[2]){r.length=s;break}if(s<0&&(!n||n==o[2]))return{tag:o[2],from:t(a,l),to:t(e.line,e.ch)}}else r.push(o[2])}}function p(e,n){for(var r=[];;){var i=d(e);if(!i)return;if("selfClose"!=i){var o=e.line,a=e.ch,l=u(e);if(!l)return;if(l[1])r.push(l[2]);else{for(var s=r.length-1;s>=0;--s)if(r[s]==l[2]){r.length=s;break}if(s<0&&(!n||n==l[2]))return{tag:l[2],from:t(e.line,e.ch),to:t(o,a)}}}else u(e)}}e.registerHelper("fold","xml",function(e,r){for(var i=new o(e,r.line,0);;){var a=f(i);if(!a||i.line!=r.line)return;var l=c(i);if(!l)return;if(!a[1]&&"selfClose"!=l){var s=t(i.line,i.ch),u=h(i,a[2]);return u&&n(u.from,s)>0?{from:s,to:u.from}:null}}}),e.findMatchingTag=function(e,r,i){var a=new o(e,r.line,r.ch,i);if(-1!=a.text.indexOf(">")||-1!=a.text.indexOf("<")){var l=c(a),s=l&&t(a.line,a.ch),f=l&&u(a);if(l&&f&&!(n(a,r)>0)){var d={from:t(a.line,a.ch),to:s,tag:f[2]};return"selfClose"==l?{open:d,close:null,at:"open"}:f[1]?{open:p(a,f[2]),close:d,at:"close"}:(a=new o(e,s.line,s.ch,i),{open:d,close:h(a,f[2]),at:"open"})}}},e.findEnclosingTag=function(e,t,n,r){for(var i=new o(e,t.line,t.ch,n);;){var a=p(i,r);if(!a)break;var l=new o(e,t.line,t.ch,n),s=h(l,a.tag);if(s)return{open:a,close:s}}},e.scanForClosingTag=function(e,t,n,r){var i=new o(e,t.line,t.ch,r?{from:0,to:r}:null);return h(i,n)}}(n(0))},function(e,t,n){!function(e){"use strict";e.registerGlobalHelper("fold","comment",function(e){return e.blockCommentStart&&e.blockCommentEnd},function(t,n){var r=t.getModeAt(n),i=r.blockCommentStart,o=r.blockCommentEnd;if(i&&o){for(var a,l=n.line,s=t.getLine(l),c=n.ch,u=0;;){var f=c<=0?-1:s.lastIndexOf(i,c-1);if(-1!=f){if(1==u&&ft.lastLine())return null;var r=t.getTokenAt(e.Pos(n,1));if(/\S/.test(r.string)||(r=t.getTokenAt(e.Pos(n,r.end+1))),"keyword"!=r.type||"import"!=r.string)return null;for(var i=n,o=Math.min(t.lastLine(),n+10);i<=o;++i){var a=t.getLine(i),l=a.indexOf(";");if(-1!=l)return{startCh:r.end,end:e.Pos(i,l)}}}var i,o=n.line,a=r(o);if(!a||r(o-1)||(i=r(o-2))&&i.end.line==o-1)return null;for(var l=a.end;;){var s=r(l.line+1);if(null==s)break;l=s.end}return{from:t.clipPos(e.Pos(o,a.startCh+1)),to:l}}),e.registerHelper("fold","include",function(t,n){function r(n){if(nt.lastLine())return null;var r=t.getTokenAt(e.Pos(n,1));return/\S/.test(r.string)||(r=t.getTokenAt(e.Pos(n,r.end+1))),"meta"==r.type&&"#include"==r.string.slice(0,8)?r.start+8:void 0}var i=n.line,o=r(i);if(null==o||null!=r(i-1))return null;for(var a=i;;){var l=r(a+1);if(null==l)break;++a}return{from:e.Pos(i,o+1),to:t.clipPos(e.Pos(a))}})}(n(0))},function(e,t,n){!function(e){"use strict";var t=e.commands,n=e.Pos;function r(t,r){t.extendSelectionsBy(function(i){return t.display.shift||t.doc.extend||i.empty()?function(t,r,i){if(i<0&&0==r.ch)return t.clipPos(n(r.line-1));var o=t.getLine(r.line);if(i>0&&r.ch>=o.length)return t.clipPos(n(r.line+1,0));for(var a,l="start",s=r.ch,c=i<0?0:o.length,u=0;s!=c;s+=i,u++){var f=o.charAt(i<0?s-1:s),d="_"!=f&&e.isWordChar(f)?"w":"o";if("w"==d&&f.toUpperCase()==f&&(d="W"),"start"==l)"o"!=d&&(l="in",a=d);else if("in"==l&&a!=d){if("w"==a&&"W"==d&&i<0&&s--,"W"==a&&"w"==d&&i>0){a="w";continue}break}}return n(r.line,s)}(t.doc,i.head,r):r<0?i.from():i.to()})}function i(t,r){if(t.isReadOnly())return e.Pass;t.operation(function(){for(var e=t.listSelections().length,i=[],o=-1,a=0;a=n&&e.execCommand("goLineUp")}e.scrollTo(null,t.top-e.defaultTextHeight())},t.scrollLineDown=function(e){var t=e.getScrollInfo();if(!e.somethingSelected()){var n=e.lineAtHeight(t.top,"local")+1;e.getCursor().line<=n&&e.execCommand("goLineDown")}e.scrollTo(null,t.top+e.defaultTextHeight())},t.splitSelectionByLine=function(e){for(var t=e.listSelections(),r=[],i=0;io.line&&l==a.line&&0==a.ch||r.push({anchor:l==o.line?o:n(l,0),head:l==a.line?a:n(l)});e.setSelections(r,0)},t.singleSelectionTop=function(e){var t=e.listSelections()[0];e.setSelection(t.anchor,t.head,{scroll:!1})},t.selectLine=function(e){for(var t=e.listSelections(),r=[],i=0;i=0;l--){var s=r[i[l]];if(!(c&&e.cmpPos(s.head,c)>0)){var u=o(t,s.head);c=u.from,t.replaceRange(n(u.word),u.from,u.to)}}})}function f(t){var n=t.getCursor("from"),r=t.getCursor("to");if(0==e.cmpPos(n,r)){var i=o(t,n);if(!i.word)return;n=i.from,r=i.to}return{from:n,to:r,query:t.getRange(n,r),word:i}}function d(e,t){var r=f(e);if(r){var i=r.query,o=e.getSearchCursor(i,t?r.to:r.from);(t?o.findNext():o.findPrevious())?e.setSelection(o.from(),o.to()):(o=e.getSearchCursor(i,t?n(e.firstLine(),0):e.clipPos(n(e.lastLine()))),(t?o.findNext():o.findPrevious())?e.setSelection(o.from(),o.to()):r.word&&e.setSelection(r.from,r.to))}}t.selectScope=function(e){s(e)||e.execCommand("selectAll")},t.selectBetweenBrackets=function(t){if(!s(t))return e.Pass},t.goToBracket=function(t){t.extendSelectionsBy(function(r){var i=t.scanForBracket(r.head,1);if(i&&0!=e.cmpPos(i.pos,r.head))return i.pos;var o=t.scanForBracket(r.head,-1);return o&&n(o.pos.line,o.pos.ch+1)||r.head})},t.swapLineUp=function(t){if(t.isReadOnly())return e.Pass;for(var r=t.listSelections(),i=[],o=t.firstLine()-1,a=[],l=0;lo?i.push(c,u):i.length&&(i[i.length-1]=u),o=u}t.operation(function(){for(var e=0;et.lastLine()?t.replaceRange("\n"+l,n(t.lastLine()),null,"+swapLine"):t.replaceRange(l+"\n",n(o,0),null,"+swapLine")}t.setSelections(a),t.scrollIntoView()})},t.swapLineDown=function(t){if(t.isReadOnly())return e.Pass;for(var r=t.listSelections(),i=[],o=t.lastLine()+1,a=r.length-1;a>=0;a--){var l=r[a],s=l.to().line+1,c=l.from().line;0!=l.to().ch||l.empty()||s--,s=0;e-=2){var r=i[e],o=i[e+1],a=t.getLine(r);r==t.lastLine()?t.replaceRange("",n(r-1),n(r),"+swapLine"):t.replaceRange("",n(r,0),n(r+1,0),"+swapLine"),t.replaceRange(a+"\n",n(o,0),null,"+swapLine")}t.scrollIntoView()})},t.toggleCommentIndented=function(e){e.toggleComment({indent:!0})},t.joinLines=function(e){for(var t=e.listSelections(),r=[],i=0;i=0;o--){var a=r[o].head,l=t.getRange({line:a.line,ch:0},a),s=e.countColumn(l,null,t.getOption("tabSize")),c=t.findPosH(a,-1,"char",!1);if(l&&!/\S/.test(l)&&s%i==0){var u=new n(a.line,e.findColumn(l,s-i,i));u.ch!=a.ch&&(c=u)}t.replaceRange("",c,a,"+delete")}})},t.delLineRight=function(e){e.operation(function(){for(var t=e.listSelections(),r=t.length-1;r>=0;r--)e.replaceRange("",t[r].anchor,n(t[r].to().line),"+delete");e.scrollIntoView()})},t.upcaseAtCursor=function(e){u(e,function(e){return e.toUpperCase()})},t.downcaseAtCursor=function(e){u(e,function(e){return e.toLowerCase()})},t.setSublimeMark=function(e){e.state.sublimeMark&&e.state.sublimeMark.clear(),e.state.sublimeMark=e.setBookmark(e.getCursor())},t.selectToSublimeMark=function(e){var t=e.state.sublimeMark&&e.state.sublimeMark.find();t&&e.setSelection(e.getCursor(),t)},t.deleteToSublimeMark=function(t){var n=t.state.sublimeMark&&t.state.sublimeMark.find();if(n){var r=t.getCursor(),i=n;if(e.cmpPos(r,i)>0){var o=i;i=r,r=o}t.state.sublimeKilled=t.getRange(r,i),t.replaceRange("",r,i)}},t.swapWithSublimeMark=function(e){var t=e.state.sublimeMark&&e.state.sublimeMark.find();t&&(e.state.sublimeMark.clear(),e.state.sublimeMark=e.setBookmark(e.getCursor()),e.setCursor(t))},t.sublimeYank=function(e){null!=e.state.sublimeKilled&&e.replaceSelection(e.state.sublimeKilled,null,"paste")},t.showInCenter=function(e){var t=e.cursorCoords(null,"local");e.scrollTo(null,(t.top+t.bottom)/2-e.getScrollInfo().clientHeight/2)},t.findUnder=function(e){d(e,!0)},t.findUnderPrevious=function(e){d(e,!1)},t.findAllUnder=function(e){var t=f(e);if(t){for(var n=e.getSearchCursor(t.query),r=[],i=-1;n.findNext();)r.push({anchor:n.from(),head:n.to()}),n.from().line<=t.from.line&&n.from().ch<=t.from.ch&&i++;e.setSelections(r,i)}};var h=e.keyMap;h.macSublime={"Cmd-Left":"goLineStartSmart","Shift-Tab":"indentLess","Shift-Ctrl-K":"deleteLine","Alt-Q":"wrapLines","Ctrl-Left":"goSubwordLeft","Ctrl-Right":"goSubwordRight","Ctrl-Alt-Up":"scrollLineUp","Ctrl-Alt-Down":"scrollLineDown","Cmd-L":"selectLine","Shift-Cmd-L":"splitSelectionByLine",Esc:"singleSelectionTop","Cmd-Enter":"insertLineAfter","Shift-Cmd-Enter":"insertLineBefore","Cmd-D":"selectNextOccurrence","Shift-Cmd-Space":"selectScope","Shift-Cmd-M":"selectBetweenBrackets","Cmd-M":"goToBracket","Cmd-Ctrl-Up":"swapLineUp","Cmd-Ctrl-Down":"swapLineDown","Cmd-/":"toggleCommentIndented","Cmd-J":"joinLines","Shift-Cmd-D":"duplicateLine",F9:"sortLines","Cmd-F9":"sortLinesInsensitive",F2:"nextBookmark","Shift-F2":"prevBookmark","Cmd-F2":"toggleBookmark","Shift-Cmd-F2":"clearBookmarks","Alt-F2":"selectBookmarks",Backspace:"smartBackspace","Cmd-K Cmd-K":"delLineRight","Cmd-K Cmd-U":"upcaseAtCursor","Cmd-K Cmd-L":"downcaseAtCursor","Cmd-K Cmd-Space":"setSublimeMark","Cmd-K Cmd-A":"selectToSublimeMark","Cmd-K Cmd-W":"deleteToSublimeMark","Cmd-K Cmd-X":"swapWithSublimeMark","Cmd-K Cmd-Y":"sublimeYank","Cmd-K Cmd-C":"showInCenter","Cmd-K Cmd-G":"clearBookmarks","Cmd-K Cmd-Backspace":"delLineLeft","Cmd-K Cmd-0":"unfoldAll","Cmd-K Cmd-J":"unfoldAll","Ctrl-Shift-Up":"addCursorToPrevLine","Ctrl-Shift-Down":"addCursorToNextLine","Cmd-F3":"findUnder","Shift-Cmd-F3":"findUnderPrevious","Alt-F3":"findAllUnder","Shift-Cmd-[":"fold","Shift-Cmd-]":"unfold","Cmd-I":"findIncremental","Shift-Cmd-I":"findIncrementalReverse","Cmd-H":"replace",F3:"findNext","Shift-F3":"findPrev",fallthrough:"macDefault"},e.normalizeKeyMap(h.macSublime),h.pcSublime={"Shift-Tab":"indentLess","Shift-Ctrl-K":"deleteLine","Alt-Q":"wrapLines","Ctrl-T":"transposeChars","Alt-Left":"goSubwordLeft","Alt-Right":"goSubwordRight","Ctrl-Up":"scrollLineUp","Ctrl-Down":"scrollLineDown","Ctrl-L":"selectLine","Shift-Ctrl-L":"splitSelectionByLine",Esc:"singleSelectionTop","Ctrl-Enter":"insertLineAfter","Shift-Ctrl-Enter":"insertLineBefore","Ctrl-D":"selectNextOccurrence","Shift-Ctrl-Space":"selectScope","Shift-Ctrl-M":"selectBetweenBrackets","Ctrl-M":"goToBracket","Shift-Ctrl-Up":"swapLineUp","Shift-Ctrl-Down":"swapLineDown","Ctrl-/":"toggleCommentIndented","Ctrl-J":"joinLines","Shift-Ctrl-D":"duplicateLine",F9:"sortLines","Ctrl-F9":"sortLinesInsensitive",F2:"nextBookmark","Shift-F2":"prevBookmark","Ctrl-F2":"toggleBookmark","Shift-Ctrl-F2":"clearBookmarks","Alt-F2":"selectBookmarks",Backspace:"smartBackspace","Ctrl-K Ctrl-K":"delLineRight","Ctrl-K Ctrl-U":"upcaseAtCursor","Ctrl-K Ctrl-L":"downcaseAtCursor","Ctrl-K Ctrl-Space":"setSublimeMark","Ctrl-K Ctrl-A":"selectToSublimeMark","Ctrl-K Ctrl-W":"deleteToSublimeMark","Ctrl-K Ctrl-X":"swapWithSublimeMark","Ctrl-K Ctrl-Y":"sublimeYank","Ctrl-K Ctrl-C":"showInCenter","Ctrl-K Ctrl-G":"clearBookmarks","Ctrl-K Ctrl-Backspace":"delLineLeft","Ctrl-K Ctrl-0":"unfoldAll","Ctrl-K Ctrl-J":"unfoldAll","Ctrl-Alt-Up":"addCursorToPrevLine","Ctrl-Alt-Down":"addCursorToNextLine","Ctrl-F3":"findUnder","Shift-Ctrl-F3":"findUnderPrevious","Alt-F3":"findAllUnder","Shift-Ctrl-[":"fold","Shift-Ctrl-]":"unfold","Ctrl-I":"findIncremental","Shift-Ctrl-I":"findIncrementalReverse","Ctrl-H":"replace",F3:"findNext","Shift-F3":"findPrev",fallthrough:"pcDefault"},e.normalizeKeyMap(h.pcSublime);var p=h.default==h.macDefault;h.sublime=p?h.macSublime:h.pcSublime}(n(0),n(1),n(4))},function(e,t,n){!function(e){"use strict";var t=[{keys:"",type:"keyToKey",toKeys:"h"},{keys:"",type:"keyToKey",toKeys:"l"},{keys:"",type:"keyToKey",toKeys:"k"},{keys:"",type:"keyToKey",toKeys:"j"},{keys:"",type:"keyToKey",toKeys:"l"},{keys:"",type:"keyToKey",toKeys:"h",context:"normal"},{keys:"",type:"keyToKey",toKeys:"W"},{keys:"",type:"keyToKey",toKeys:"B",context:"normal"},{keys:"",type:"keyToKey",toKeys:"w"},{keys:"",type:"keyToKey",toKeys:"b",context:"normal"},{keys:"",type:"keyToKey",toKeys:"j"},{keys:"",type:"keyToKey",toKeys:"k"},{keys:"",type:"keyToKey",toKeys:""},{keys:"",type:"keyToKey",toKeys:""},{keys:"",type:"keyToKey",toKeys:"",context:"insert"},{keys:"",type:"keyToKey",toKeys:"",context:"insert"},{keys:"s",type:"keyToKey",toKeys:"cl",context:"normal"},{keys:"s",type:"keyToKey",toKeys:"c",context:"visual"},{keys:"S",type:"keyToKey",toKeys:"cc",context:"normal"},{keys:"S",type:"keyToKey",toKeys:"VdO",context:"visual"},{keys:"",type:"keyToKey",toKeys:"0"},{keys:"",type:"keyToKey",toKeys:"$"},{keys:"",type:"keyToKey",toKeys:""},{keys:"",type:"keyToKey",toKeys:""},{keys:"",type:"keyToKey",toKeys:"j^",context:"normal"},{keys:"",type:"action",action:"toggleOverwrite",context:"insert"},{keys:"H",type:"motion",motion:"moveToTopLine",motionArgs:{linewise:!0,toJumplist:!0}},{keys:"M",type:"motion",motion:"moveToMiddleLine",motionArgs:{linewise:!0,toJumplist:!0}},{keys:"L",type:"motion",motion:"moveToBottomLine",motionArgs:{linewise:!0,toJumplist:!0}},{keys:"h",type:"motion",motion:"moveByCharacters",motionArgs:{forward:!1}},{keys:"l",type:"motion",motion:"moveByCharacters",motionArgs:{forward:!0}},{keys:"j",type:"motion",motion:"moveByLines",motionArgs:{forward:!0,linewise:!0}},{keys:"k",type:"motion",motion:"moveByLines",motionArgs:{forward:!1,linewise:!0}},{keys:"gj",type:"motion",motion:"moveByDisplayLines",motionArgs:{forward:!0}},{keys:"gk",type:"motion",motion:"moveByDisplayLines",motionArgs:{forward:!1}},{keys:"w",type:"motion",motion:"moveByWords",motionArgs:{forward:!0,wordEnd:!1}},{keys:"W",type:"motion",motion:"moveByWords",motionArgs:{forward:!0,wordEnd:!1,bigWord:!0}},{keys:"e",type:"motion",motion:"moveByWords",motionArgs:{forward:!0,wordEnd:!0,inclusive:!0}},{keys:"E",type:"motion",motion:"moveByWords",motionArgs:{forward:!0,wordEnd:!0,bigWord:!0,inclusive:!0}},{keys:"b",type:"motion",motion:"moveByWords",motionArgs:{forward:!1,wordEnd:!1}},{keys:"B",type:"motion",motion:"moveByWords",motionArgs:{forward:!1,wordEnd:!1,bigWord:!0}},{keys:"ge",type:"motion",motion:"moveByWords",motionArgs:{forward:!1,wordEnd:!0,inclusive:!0}},{keys:"gE",type:"motion",motion:"moveByWords",motionArgs:{forward:!1,wordEnd:!0,bigWord:!0,inclusive:!0}},{keys:"{",type:"motion",motion:"moveByParagraph",motionArgs:{forward:!1,toJumplist:!0}},{keys:"}",type:"motion",motion:"moveByParagraph",motionArgs:{forward:!0,toJumplist:!0}},{keys:"(",type:"motion",motion:"moveBySentence",motionArgs:{forward:!1}},{keys:")",type:"motion",motion:"moveBySentence",motionArgs:{forward:!0}},{keys:"",type:"motion",motion:"moveByPage",motionArgs:{forward:!0}},{keys:"",type:"motion",motion:"moveByPage",motionArgs:{forward:!1}},{keys:"",type:"motion",motion:"moveByScroll",motionArgs:{forward:!0,explicitRepeat:!0}},{keys:"",type:"motion",motion:"moveByScroll",motionArgs:{forward:!1,explicitRepeat:!0}},{keys:"gg",type:"motion",motion:"moveToLineOrEdgeOfDocument",motionArgs:{forward:!1,explicitRepeat:!0,linewise:!0,toJumplist:!0}},{keys:"G",type:"motion",motion:"moveToLineOrEdgeOfDocument",motionArgs:{forward:!0,explicitRepeat:!0,linewise:!0,toJumplist:!0}},{keys:"0",type:"motion",motion:"moveToStartOfLine"},{keys:"^",type:"motion",motion:"moveToFirstNonWhiteSpaceCharacter"},{keys:"+",type:"motion",motion:"moveByLines",motionArgs:{forward:!0,toFirstChar:!0}},{keys:"-",type:"motion",motion:"moveByLines",motionArgs:{forward:!1,toFirstChar:!0}},{keys:"_",type:"motion",motion:"moveByLines",motionArgs:{forward:!0,toFirstChar:!0,repeatOffset:-1}},{keys:"$",type:"motion",motion:"moveToEol",motionArgs:{inclusive:!0}},{keys:"%",type:"motion",motion:"moveToMatchedSymbol",motionArgs:{inclusive:!0,toJumplist:!0}},{keys:"f",type:"motion",motion:"moveToCharacter",motionArgs:{forward:!0,inclusive:!0}},{keys:"F",type:"motion",motion:"moveToCharacter",motionArgs:{forward:!1}},{keys:"t",type:"motion",motion:"moveTillCharacter",motionArgs:{forward:!0,inclusive:!0}},{keys:"T",type:"motion",motion:"moveTillCharacter",motionArgs:{forward:!1}},{keys:";",type:"motion",motion:"repeatLastCharacterSearch",motionArgs:{forward:!0}},{keys:",",type:"motion",motion:"repeatLastCharacterSearch",motionArgs:{forward:!1}},{keys:"'",type:"motion",motion:"goToMark",motionArgs:{toJumplist:!0,linewise:!0}},{keys:"`",type:"motion",motion:"goToMark",motionArgs:{toJumplist:!0}},{keys:"]`",type:"motion",motion:"jumpToMark",motionArgs:{forward:!0}},{keys:"[`",type:"motion",motion:"jumpToMark",motionArgs:{forward:!1}},{keys:"]'",type:"motion",motion:"jumpToMark",motionArgs:{forward:!0,linewise:!0}},{keys:"['",type:"motion",motion:"jumpToMark",motionArgs:{forward:!1,linewise:!0}},{keys:"]p",type:"action",action:"paste",isEdit:!0,actionArgs:{after:!0,isEdit:!0,matchIndent:!0}},{keys:"[p",type:"action",action:"paste",isEdit:!0,actionArgs:{after:!1,isEdit:!0,matchIndent:!0}},{keys:"]",type:"motion",motion:"moveToSymbol",motionArgs:{forward:!0,toJumplist:!0}},{keys:"[",type:"motion",motion:"moveToSymbol",motionArgs:{forward:!1,toJumplist:!0}},{keys:"|",type:"motion",motion:"moveToColumn"},{keys:"o",type:"motion",motion:"moveToOtherHighlightedEnd",context:"visual"},{keys:"O",type:"motion",motion:"moveToOtherHighlightedEnd",motionArgs:{sameLine:!0},context:"visual"},{keys:"d",type:"operator",operator:"delete"},{keys:"y",type:"operator",operator:"yank"},{keys:"c",type:"operator",operator:"change"},{keys:">",type:"operator",operator:"indent",operatorArgs:{indentRight:!0}},{keys:"<",type:"operator",operator:"indent",operatorArgs:{indentRight:!1}},{keys:"g~",type:"operator",operator:"changeCase"},{keys:"gu",type:"operator",operator:"changeCase",operatorArgs:{toLower:!0},isEdit:!0},{keys:"gU",type:"operator",operator:"changeCase",operatorArgs:{toLower:!1},isEdit:!0},{keys:"n",type:"motion",motion:"findNext",motionArgs:{forward:!0,toJumplist:!0}},{keys:"N",type:"motion",motion:"findNext",motionArgs:{forward:!1,toJumplist:!0}},{keys:"x",type:"operatorMotion",operator:"delete",motion:"moveByCharacters",motionArgs:{forward:!0},operatorMotionArgs:{visualLine:!1}},{keys:"X",type:"operatorMotion",operator:"delete",motion:"moveByCharacters",motionArgs:{forward:!1},operatorMotionArgs:{visualLine:!0}},{keys:"D",type:"operatorMotion",operator:"delete",motion:"moveToEol",motionArgs:{inclusive:!0},context:"normal"},{keys:"D",type:"operator",operator:"delete",operatorArgs:{linewise:!0},context:"visual"},{keys:"Y",type:"operatorMotion",operator:"yank",motion:"expandToLine",motionArgs:{linewise:!0},context:"normal"},{keys:"Y",type:"operator",operator:"yank",operatorArgs:{linewise:!0},context:"visual"},{keys:"C",type:"operatorMotion",operator:"change",motion:"moveToEol",motionArgs:{inclusive:!0},context:"normal"},{keys:"C",type:"operator",operator:"change",operatorArgs:{linewise:!0},context:"visual"},{keys:"~",type:"operatorMotion",operator:"changeCase",motion:"moveByCharacters",motionArgs:{forward:!0},operatorArgs:{shouldMoveCursor:!0},context:"normal"},{keys:"~",type:"operator",operator:"changeCase",context:"visual"},{keys:"",type:"operatorMotion",operator:"delete",motion:"moveByWords",motionArgs:{forward:!1,wordEnd:!1},context:"insert"},{keys:"",type:"action",action:"jumpListWalk",actionArgs:{forward:!0}},{keys:"",type:"action",action:"jumpListWalk",actionArgs:{forward:!1}},{keys:"",type:"action",action:"scroll",actionArgs:{forward:!0,linewise:!0}},{keys:"",type:"action",action:"scroll",actionArgs:{forward:!1,linewise:!0}},{keys:"a",type:"action",action:"enterInsertMode",isEdit:!0,actionArgs:{insertAt:"charAfter"},context:"normal"},{keys:"A",type:"action",action:"enterInsertMode",isEdit:!0,actionArgs:{insertAt:"eol"},context:"normal"},{keys:"A",type:"action",action:"enterInsertMode",isEdit:!0,actionArgs:{insertAt:"endOfSelectedArea"},context:"visual"},{keys:"i",type:"action",action:"enterInsertMode",isEdit:!0,actionArgs:{insertAt:"inplace"},context:"normal"},{keys:"I",type:"action",action:"enterInsertMode",isEdit:!0,actionArgs:{insertAt:"firstNonBlank"},context:"normal"},{keys:"I",type:"action",action:"enterInsertMode",isEdit:!0,actionArgs:{insertAt:"startOfSelectedArea"},context:"visual"},{keys:"o",type:"action",action:"newLineAndEnterInsertMode",isEdit:!0,interlaceInsertRepeat:!0,actionArgs:{after:!0},context:"normal"},{keys:"O",type:"action",action:"newLineAndEnterInsertMode",isEdit:!0,interlaceInsertRepeat:!0,actionArgs:{after:!1},context:"normal"},{keys:"v",type:"action",action:"toggleVisualMode"},{keys:"V",type:"action",action:"toggleVisualMode",actionArgs:{linewise:!0}},{keys:"",type:"action",action:"toggleVisualMode",actionArgs:{blockwise:!0}},{keys:"",type:"action",action:"toggleVisualMode",actionArgs:{blockwise:!0}},{keys:"gv",type:"action",action:"reselectLastSelection"},{keys:"J",type:"action",action:"joinLines",isEdit:!0},{keys:"p",type:"action",action:"paste",isEdit:!0,actionArgs:{after:!0,isEdit:!0}},{keys:"P",type:"action",action:"paste",isEdit:!0,actionArgs:{after:!1,isEdit:!0}},{keys:"r",type:"action",action:"replace",isEdit:!0},{keys:"@",type:"action",action:"replayMacro"},{keys:"q",type:"action",action:"enterMacroRecordMode"},{keys:"R",type:"action",action:"enterInsertMode",isEdit:!0,actionArgs:{replace:!0}},{keys:"u",type:"action",action:"undo",context:"normal"},{keys:"u",type:"operator",operator:"changeCase",operatorArgs:{toLower:!0},context:"visual",isEdit:!0},{keys:"U",type:"operator",operator:"changeCase",operatorArgs:{toLower:!1},context:"visual",isEdit:!0},{keys:"",type:"action",action:"redo"},{keys:"m",type:"action",action:"setMark"},{keys:'"',type:"action",action:"setRegister"},{keys:"zz",type:"action",action:"scrollToCursor",actionArgs:{position:"center"}},{keys:"z.",type:"action",action:"scrollToCursor",actionArgs:{position:"center"},motion:"moveToFirstNonWhiteSpaceCharacter"},{keys:"zt",type:"action",action:"scrollToCursor",actionArgs:{position:"top"}},{keys:"z",type:"action",action:"scrollToCursor",actionArgs:{position:"top"},motion:"moveToFirstNonWhiteSpaceCharacter"},{keys:"z-",type:"action",action:"scrollToCursor",actionArgs:{position:"bottom"}},{keys:"zb",type:"action",action:"scrollToCursor",actionArgs:{position:"bottom"},motion:"moveToFirstNonWhiteSpaceCharacter"},{keys:".",type:"action",action:"repeatLastEdit"},{keys:"",type:"action",action:"incrementNumberToken",isEdit:!0,actionArgs:{increase:!0,backtrack:!1}},{keys:"",type:"action",action:"incrementNumberToken",isEdit:!0,actionArgs:{increase:!1,backtrack:!1}},{keys:"",type:"action",action:"indent",actionArgs:{indentRight:!0},context:"insert"},{keys:"",type:"action",action:"indent",actionArgs:{indentRight:!1},context:"insert"},{keys:"a",type:"motion",motion:"textObjectManipulation"},{keys:"i",type:"motion",motion:"textObjectManipulation",motionArgs:{textObjectInner:!0}},{keys:"/",type:"search",searchArgs:{forward:!0,querySrc:"prompt",toJumplist:!0}},{keys:"?",type:"search",searchArgs:{forward:!1,querySrc:"prompt",toJumplist:!0}},{keys:"*",type:"search",searchArgs:{forward:!0,querySrc:"wordUnderCursor",wholeWordOnly:!0,toJumplist:!0}},{keys:"#",type:"search",searchArgs:{forward:!1,querySrc:"wordUnderCursor",wholeWordOnly:!0,toJumplist:!0}},{keys:"g*",type:"search",searchArgs:{forward:!0,querySrc:"wordUnderCursor",toJumplist:!0}},{keys:"g#",type:"search",searchArgs:{forward:!1,querySrc:"wordUnderCursor",toJumplist:!0}},{keys:":",type:"ex"}],n=[{name:"colorscheme",shortName:"colo"},{name:"map"},{name:"imap",shortName:"im"},{name:"nmap",shortName:"nm"},{name:"vmap",shortName:"vm"},{name:"unmap"},{name:"write",shortName:"w"},{name:"undo",shortName:"u"},{name:"redo",shortName:"red"},{name:"set",shortName:"se"},{name:"set",shortName:"se"},{name:"setlocal",shortName:"setl"},{name:"setglobal",shortName:"setg"},{name:"sort",shortName:"sor"},{name:"substitute",shortName:"s",possiblyAsync:!0},{name:"nohlsearch",shortName:"noh"},{name:"yank",shortName:"y"},{name:"delmarks",shortName:"delm"},{name:"registers",shortName:"reg",excludeFromCommandHistory:!0},{name:"global",shortName:"g"}],r=e.Pos;e.Vim=function(){function i(t,n){this==e.keyMap.vim&&(e.rmClass(t.getWrapperElement(),"cm-fat-cursor"),"contenteditable"==t.getOption("inputStyle")&&null!=document.body.style.caretColor&&(function(e){var t=e.state.fatCursorMarks;if(t)for(var n=0;n")}(t);if(!r)return!1;var i=e.Vim.findKey(n,r);return"function"==typeof i&&e.signal(n,"vim-keypress",r),i}}e.defineOption("vimMode",!1,function(t,n,r){n&&"vim"!=t.getOption("keyMap")?t.setOption("keyMap","vim"):!n&&r!=e.Init&&/^vim/.test(t.getOption("keyMap"))&&t.setOption("keyMap","default")});var c={Shift:"S",Ctrl:"C",Alt:"A",Cmd:"D",Mod:"A"},u={Enter:"CR",Backspace:"BS",Delete:"Del",Insert:"Ins"};function f(e){var t=e.state.vim;return t.onPasteFn||(t.onPasteFn=function(){t.insertMode||(e.setCursor(Z(e.getCursor(),0,1)),G.enterInsertMode(e,{},t))}),t.onPasteFn}var d=/[\d]/,h=[e.isWordChar,function(t){return t&&!e.isWordChar(t)&&!/\s/.test(t)}],p=[function(e){return/\S/.test(e)}];function m(e,t){for(var n=[],r=e;r"]),x=[].concat(g,v,y,["-",'"',".",":","/"]);function w(e,t){return t>=e.firstLine()&&t<=e.lastLine()}function k(e){return/^[a-z]$/.test(e)}function C(e){return/^[A-Z]$/.test(e)}function S(e){return/^\s*$/.test(e)}function L(e){return-1!=".?!".indexOf(e)}function M(e,t){for(var n=0;nn?t=n:t0?1:-1,u=o.getCursor();do{if((l=i[(e+(t+=c))%e])&&(s=l.find())&&!te(u,s))break}while(tr)}return l}}},R=function(e){return e?{changes:e.changes,expectCursorActivityForChange:e.expectCursorActivityForChange}:{changes:[],expectCursorActivityForChange:!1}};function B(){this.latestRegister=void 0,this.isPlaying=!1,this.isRecording=!1,this.replaySearchQueries=[],this.onRecordingDone=void 0,this.lastInsertModeChanges=R()}function D(e){return e.state.vim||(e.state.vim={inputState:new z,lastEditInputState:void 0,lastEditActionCommand:void 0,lastHPos:-1,lastHSPos:-1,lastMotion:null,marks:{},fakeCursor:null,insertMode:!1,insertModeRepeat:void 0,visualMode:!1,visualLine:!1,visualBlock:!1,lastSelection:null,lastPastedText:null,sel:{},options:{}}),e.state.vim}function F(){for(var e in N={searchQuery:null,searchIsReversed:!1,lastSubstituteReplacePart:void 0,jumpList:I(),macroModeState:new B,lastCharacterSearch:{increment:0,forward:!0,selectedCharacter:""},registerController:new K({}),searchHistoryController:new j,exCommandHistoryController:new j},T){var t=T[e];t.value=t.defaultValue}}B.prototype={exitMacroRecordMode:function(){var e=N.macroModeState;e.onRecordingDone&&e.onRecordingDone(),e.onRecordingDone=void 0,e.isRecording=!1},enterMacroRecordMode:function(e,t){var n=N.registerController.getRegister(t);n&&(n.clear(),this.latestRegister=t,e.openDialog&&(this.onRecordingDone=e.openDialog("(recording)["+t+"]",null,{bottom:!0})),this.isRecording=!0)}};var W={buildKeyMap:function(){},getRegisterController:function(){return N.registerController},resetVimGlobalState_:F,getVimGlobalState_:function(){return N},maybeInitVimState_:D,suppressErrorLogging:!1,InsertModeKey:Je,map:function(e,t,n){Ve.map(e,t,n)},unmap:function(e,t){Ve.unmap(e,t)},setOption:O,getOption:E,defineOption:A,defineEx:function(e,t,n){if(t){if(0!==e.indexOf(t))throw new Error('(Vim.defineEx) "'+t+'" is not a prefix of "'+e+'", command not registered')}else t=e;Ue[e]=n,Ve.commandMap_[t]={name:e,shortName:t,type:"api"}},handleKey:function(e,t,n){var r=this.findKey(e,t,n);if("function"==typeof r)return r()},findKey:function(n,r,i){var o,a=D(n);function l(){var e=N.macroModeState;if(e.isRecording){if("q"==r)return e.exitMacroRecordMode(),_(n),!0;"mapping"!=i&&function(e,t){if(!e.isPlaying){var n=e.latestRegister,r=N.registerController.getRegister(n);r&&r.pushText(t)}}(e,r)}}function s(){if(""==r)return _(n),a.visualMode?pe(n):a.insertMode&&qe(n),!0}return!1===(o=a.insertMode?function(){if(s())return!0;for(var e=a.inputState.keyBuffer=a.inputState.keyBuffer+r,i=1==r.length,o=U.matchCommand(e,t,a.inputState,"insert");e.length>1&&"full"!=o.type;){var e=a.inputState.keyBuffer=e.slice(1),l=U.matchCommand(e,t,a.inputState,"insert");"none"!=l.type&&(o=l)}if("none"==o.type)return _(n),!1;if("partial"==o.type)return P&&window.clearTimeout(P),P=window.setTimeout(function(){a.insertMode&&a.inputState.keyBuffer&&_(n)},E("insertModeEscKeysTimeout")),!i;if(P&&window.clearTimeout(P),i){for(var c=n.listSelections(),u=0;u|<\w+>|./.exec(t),r=i[0],t=t.substring(i.index+r.length),e.Vim.handleKey(n,r,"mapping")}(o.toKeys):U.processCommand(n,a,o)}catch(t){throw n.state.vim=void 0,D(n),e.Vim.suppressErrorLogging||console.log(t),t}return!0})}},handleEx:function(e,t){Ve.processCommand(e,t)},defineMotion:function(e,t){V[e]=t},defineAction:function(e,t){G[e]=t},defineOperator:function(e,t){$[e]=t},mapCommand:function(e,t,n,r,i){var o={keys:e,type:t};for(var a in o[t]=n,o[t+"Args"]=r,i)o[a]=i[a];$e(o)},_mapCommand:$e,defineRegister:function(e,t){var n=N.registerController.registers;if(!e||1!=e.length)throw Error("Register name must be 1 character");if(n[e])throw Error("Register already defined "+e);n[e]=t,x.push(e)},exitVisualMode:pe,exitInsertMode:qe};function z(){this.prefixRepeat=[],this.motionRepeat=[],this.operator=null,this.operatorArgs=null,this.motion=null,this.motionArgs=null,this.keyBuffer=[],this.registerName=null}function _(t,n){t.state.vim.inputState=new z,e.signal(t,"vim-command-done",n)}function H(e,t,n){this.clear(),this.keyBuffer=[e||""],this.insertModeChanges=[],this.searchQueries=[],this.linewise=!!t,this.blockwise=!!n}function K(e){this.registers=e,this.unnamedRegister=e['"']=new H,e["."]=new H,e[":"]=new H,e["/"]=new H}function j(){this.historyBuffer=[],this.iterator=0,this.initialPrefix=null}z.prototype.pushRepeatDigit=function(e){this.operator?this.motionRepeat=this.motionRepeat.concat(e):this.prefixRepeat=this.prefixRepeat.concat(e)},z.prototype.getRepeat=function(){var e=0;return(this.prefixRepeat.length>0||this.motionRepeat.length>0)&&(e=1,this.prefixRepeat.length>0&&(e*=parseInt(this.prefixRepeat.join(""),10)),this.motionRepeat.length>0&&(e*=parseInt(this.motionRepeat.join(""),10))),e},H.prototype={setText:function(e,t,n){this.keyBuffer=[e||""],this.linewise=!!t,this.blockwise=!!n},pushText:function(e,t){t&&(this.linewise||this.keyBuffer.push("\n"),this.linewise=!0),this.keyBuffer.push(e)},pushInsertModeChanges:function(e){this.insertModeChanges.push(R(e))},pushSearchQuery:function(e){this.searchQueries.push(e)},clear:function(){this.keyBuffer=[],this.insertModeChanges=[],this.searchQueries=[],this.linewise=!1},toString:function(){return this.keyBuffer.join("")}},K.prototype={pushText:function(e,t,n,r,i){r&&"\n"!==n.charAt(n.length-1)&&(n+="\n");var o=this.isValidRegister(e)?this.getRegister(e):null;if(o){var a=C(e);a?o.pushText(n,r):o.setText(n,r,i),this.unnamedRegister.setText(o.toString(),r)}else{switch(t){case"yank":this.registers[0]=new H(n,r,i);break;case"delete":case"change":-1==n.indexOf("\n")?this.registers["-"]=new H(n,r):(this.shiftNumericRegisters_(),this.registers[1]=new H(n,r))}this.unnamedRegister.setText(n,r,i)}},getRegister:function(e){return this.isValidRegister(e)?(e=e.toLowerCase(),this.registers[e]||(this.registers[e]=new H),this.registers[e]):this.unnamedRegister},isValidRegister:function(e){return e&&M(e,x)},shiftNumericRegisters_:function(){for(var e=9;e>=2;e--)this.registers[e]=this.getRegister(""+(e-1))}},j.prototype={nextMatch:function(e,t){var n=this.historyBuffer,r=t?-1:1;null===this.initialPrefix&&(this.initialPrefix=e);for(var i=this.iterator+r;t?i>=0:i=n.length?(this.iterator=n.length,this.initialPrefix):i<0?e:void 0},pushInput:function(e){var t=this.historyBuffer.indexOf(e);t>-1&&this.historyBuffer.splice(t,1),e.length&&this.historyBuffer.push(e)},reset:function(){this.initialPrefix=null,this.iterator=this.historyBuffer.length}};var U={matchCommand:function(e,t,n,r){var i,o=function(e,t,n,r){for(var i,o=[],a=[],l=0;l"==i.keys.slice(-11)){var s=function(e){var t=/^.*(<[^>]+>)$/.exec(e),n=t?t[1]:e.slice(-1);if(n.length>1)switch(n){case"":n="\n";break;case"":n=" ";break;default:n=""}return n}(e);if(!s)return{type:"none"};n.selectedCharacter=s}return{type:"full",command:i}},processCommand:function(e,t,n){switch(t.inputState.repeatOverride=n.repeatOverride,n.type){case"motion":this.processMotion(e,t,n);break;case"operator":this.processOperator(e,t,n);break;case"operatorMotion":this.processOperatorMotion(e,t,n);break;case"action":this.processAction(e,t,n);break;case"search":this.processSearch(e,t,n);break;case"ex":case"keyToEx":this.processEx(e,t,n)}},processMotion:function(e,t,n){t.inputState.motion=n.motion,t.inputState.motionArgs=Y(n.motionArgs),this.evalInput(e,t)},processOperator:function(e,t,n){var r=t.inputState;if(r.operator){if(r.operator==n.operator)return r.motion="expandToLine",r.motionArgs={linewise:!0},void this.evalInput(e,t);_(e)}r.operator=n.operator,r.operatorArgs=Y(n.operatorArgs),t.visualMode&&this.evalInput(e,t)},processOperatorMotion:function(e,t,n){var r=t.visualMode,i=Y(n.operatorMotionArgs);i&&r&&i.visualLine&&(t.visualLine=!0),this.processOperator(e,t,n),r||this.processMotion(e,t,n)},processAction:function(e,t,n){var r=t.inputState,i=r.getRepeat(),o=!!i,a=Y(n.actionArgs)||{};r.selectedCharacter&&(a.selectedCharacter=r.selectedCharacter),n.operator&&this.processOperator(e,t,n),n.motion&&this.processMotion(e,t,n),(n.motion||n.operator)&&this.evalInput(e,t),a.repeat=i||1,a.repeatIsExplicit=o,a.registerName=r.registerName,_(e),t.lastMotion=null,n.isEdit&&this.recordLastEdit(t,r,n),G[n.action](e,a,t)},processSearch:function(t,n,r){if(t.getSearchCursor){var i=r.searchArgs.forward,o=r.searchArgs.wholeWordOnly;Te(t).setReversed(!i);var a=i?"/":"?",l=Te(t).getQuery(),s=t.getScrollInfo();switch(r.searchArgs.querySrc){case"prompt":var c=N.macroModeState;if(c.isPlaying){var u=c.replaySearchQueries.shift();h(u,!0,!1)}else De(t,{onClose:function(e){t.scrollTo(s.left,s.top),h(e,!0,!0);var n=N.macroModeState;n.isRecording&&function(e,t){if(!e.isPlaying){var n=e.latestRegister,r=N.registerController.getRegister(n);r&&r.pushSearchQuery&&r.pushSearchQuery(t)}}(n,e)},prefix:a,desc:Be,onKeyUp:function(n,r,o){var a,l,c,u=e.keyName(n);"Up"==u||"Down"==u?(a="Up"==u,l=n.target?n.target.selectionEnd:0,r=N.searchHistoryController.nextMatch(r,a)||"",o(r),l&&n.target&&(n.target.selectionEnd=n.target.selectionStart=Math.min(l,n.target.value.length))):"Left"!=u&&"Right"!=u&&"Ctrl"!=u&&"Alt"!=u&&"Shift"!=u&&N.searchHistoryController.reset();try{c=Fe(t,r,!0,!0)}catch(n){}c?t.scrollIntoView(ze(t,!i,c),30):(_e(t),t.scrollTo(s.left,s.top))},onKeyDown:function(n,r,i){var o=e.keyName(n);"Esc"==o||"Ctrl-C"==o||"Ctrl-["==o||"Backspace"==o&&""==r?(N.searchHistoryController.pushInput(r),N.searchHistoryController.reset(),Fe(t,l),_e(t),t.scrollTo(s.left,s.top),e.e_stop(n),_(t),i(),t.focus()):"Up"==o||"Down"==o?e.e_stop(n):"Ctrl-U"==o&&(e.e_stop(n),i(""))}});break;case"wordUnderCursor":var f=ge(t,!1,0,!1,!0),d=!0;if(f||(f=ge(t,!1,0,!1,!1),d=!1),!f)return;var u=t.getLine(f.start.line).substring(f.start.ch,f.end.ch);u=d&&o?"\\b"+u+"\\b":u.replace(/([.?*+$\[\]\/\\(){}|\-])/g,"\\$1"),N.jumpList.cachedCursor=t.getCursor(),t.setCursor(f.start),h(u,!0,!1)}}function h(e,i,o){N.searchHistoryController.pushInput(e),N.searchHistoryController.reset();try{Fe(t,e,i,o)}catch(n){return Re(t,"Invalid regex: "+e),void _(t)}U.processMotion(t,n,{type:"motion",motion:"findNext",motionArgs:{forward:!0,toJumplist:r.searchArgs.toJumplist}})}},processEx:function(t,n,r){function i(e){N.exCommandHistoryController.pushInput(e),N.exCommandHistoryController.reset(),Ve.processCommand(t,e)}function o(n,r,i){var o,a,l=e.keyName(n);("Esc"==l||"Ctrl-C"==l||"Ctrl-["==l||"Backspace"==l&&""==r)&&(N.exCommandHistoryController.pushInput(r),N.exCommandHistoryController.reset(),e.e_stop(n),_(t),i(),t.focus()),"Up"==l||"Down"==l?(e.e_stop(n),o="Up"==l,a=n.target?n.target.selectionEnd:0,r=N.exCommandHistoryController.nextMatch(r,o)||"",i(r),a&&n.target&&(n.target.selectionEnd=n.target.selectionStart=Math.min(a,n.target.value.length))):"Ctrl-U"==l?(e.e_stop(n),i("")):"Left"!=l&&"Right"!=l&&"Ctrl"!=l&&"Alt"!=l&&"Shift"!=l&&N.exCommandHistoryController.reset()}"keyToEx"==r.type?Ve.processCommand(t,r.exArgs.input):n.visualMode?De(t,{onClose:i,prefix:":",value:"'<,'>",onKeyDown:o,selectValueOnOpen:!1}):De(t,{onClose:i,prefix:":",onKeyDown:o})},evalInput:function(e,t){var n,i,o,a=t.inputState,l=a.motion,s=a.motionArgs||{},c=a.operator,u=a.operatorArgs||{},f=a.registerName,d=t.sel,h=ee(t.visualMode?X(e,d.head):e.getCursor("head")),p=ee(t.visualMode?X(e,d.anchor):e.getCursor("anchor")),m=ee(h),g=ee(p);if(c&&this.recordLastEdit(t,a),(o=void 0!==a.repeatOverride?a.repeatOverride:a.getRepeat())>0&&s.explicitRepeat?s.repeatIsExplicit=!0:(s.noRepeat||!s.explicitRepeat&&0===o)&&(o=1,s.repeatIsExplicit=!1),a.selectedCharacter&&(s.selectedCharacter=u.selectedCharacter=a.selectedCharacter),s.repeat=o,_(e),l){var v=V[l](e,h,s,t);if(t.lastMotion=V[l],!v)return;if(s.toJumplist){var y=N.jumpList,b=y.cachedCursor;b?(ve(e,b,v),delete y.cachedCursor):ve(e,h,v)}v instanceof Array?(i=v[0],n=v[1]):n=v,n||(n=ee(h)),t.visualMode?(t.visualBlock&&n.ch===1/0||(n=X(e,n,t.visualBlock)),i&&(i=X(e,i,!0)),i=i||g,d.anchor=i,d.head=n,de(e),Ce(e,t,"<",ne(i,n)?i:n),Ce(e,t,">",ne(i,n)?n:i)):c||(n=X(e,n),e.setCursor(n.line,n.ch))}if(c){if(u.lastSel){i=g;var x=u.lastSel,w=Math.abs(x.head.line-x.anchor.line),k=Math.abs(x.head.ch-x.anchor.ch);n=x.visualLine?r(g.line+w,g.ch):x.visualBlock?r(g.line+w,g.ch+k):x.head.line==x.anchor.line?r(g.line,g.ch+k):r(g.line+w,g.ch),t.visualMode=!0,t.visualLine=x.visualLine,t.visualBlock=x.visualBlock,d=t.sel={anchor:i,head:n},de(e)}else t.visualMode&&(u.lastSel={anchor:ee(d.anchor),head:ee(d.head),visualBlock:t.visualBlock,visualLine:t.visualLine});var C,L,M,T,A;if(t.visualMode){if(C=re(d.head,d.anchor),L=ie(d.head,d.anchor),M=t.visualLine||u.linewise,T=t.visualBlock?"block":M?"line":"char",A=he(e,{anchor:C,head:L},T),M){var O=A.ranges;if("block"==T)for(var E=0;E0&&o&&S(o);o=i.pop())n.line--,n.ch=0;o?(n.line--,n.ch=ae(e,n.line)):n.ch=0}}(e,C,L),T="char";var I=!s.inclusive||M;A=he(e,{anchor:C,head:L},T,I)}e.setSelections(A.ranges,A.primary),t.lastMotion=null,u.repeat=o,u.registerName=f,u.linewise=M;var R=$[c](e,u,A.ranges,g,n);t.visualMode&&pe(e,null!=R),R&&e.setCursor(R)}},recordLastEdit:function(e,t,n){var r=N.macroModeState;r.isPlaying||(e.lastEditInputState=t,e.lastEditActionCommand=n,r.lastInsertModeChanges.changes=[],r.lastInsertModeChanges.expectCursorActivityForChange=!1)}},V={moveToTopLine:function(e,t,n){var i=He(e).top+n.repeat-1;return r(i,me(e.getLine(i)))},moveToMiddleLine:function(e){var t=He(e),n=Math.floor(.5*(t.top+t.bottom));return r(n,me(e.getLine(n)))},moveToBottomLine:function(e,t,n){var i=He(e).bottom-n.repeat+1;return r(i,me(e.getLine(i)))},expandToLine:function(e,t,n){var i=t;return r(i.line+n.repeat-1,1/0)},findNext:function(e,t,n){var r=Te(e),i=r.getQuery();if(i){var o=!n.forward;return o=r.isReversed()?!o:o,We(e,i),ze(e,o,i,n.repeat)}},goToMark:function(e,t,n,r){var i=Ke(e,r,n.selectedCharacter);return i?n.linewise?{line:i.line,ch:me(e.getLine(i.line))}:i:null},moveToOtherHighlightedEnd:function(e,t,n,i){if(i.visualBlock&&n.sameLine){var o=i.sel;return[X(e,r(o.anchor.line,o.head.ch)),X(e,r(o.head.line,o.anchor.ch))]}return[i.sel.head,i.sel.anchor]},jumpToMark:function(e,t,n,i){for(var o=t,a=0;au&&o.line==u?this.moveToEol(e,t,n,i):(n.toFirstChar&&(a=me(e.getLine(s)),i.lastHPos=a),i.lastHSPos=e.charCoords(r(s,a),"div").left,r(s,a))},moveByDisplayLines:function(e,t,n,i){var o=t;switch(i.lastMotion){case this.moveByDisplayLines:case this.moveByScroll:case this.moveByLines:case this.moveToColumn:case this.moveToEol:break;default:i.lastHSPos=e.charCoords(o,"div").left}var a=n.repeat,l=e.findPosV(o,n.forward?a:-a,"line",i.lastHSPos);if(l.hitSide)if(n.forward)var s=e.charCoords(l,"div"),c={top:s.top+8,left:i.lastHSPos},l=e.coordsChar(c,"div");else{var u=e.charCoords(r(e.firstLine(),0),"div");u.left=i.lastHSPos,l=e.coordsChar(u,"div")}return i.lastHPos=l.ch,l},moveByPage:function(e,t,n){var r=t,i=n.repeat;return e.findPosV(r,n.forward?i:-i,"page")},moveByParagraph:function(e,t,n){var r=n.forward?1:-1;return Le(e,t,n.repeat,r)},moveBySentence:function(e,t,n){var i=n.forward?1:-1;return function(e,t,n,i){function o(e,t){if(t.pos+t.dir<0||t.pos+t.dir>=t.line.length){if(t.ln+=t.dir,!w(e,t.ln))return t.line=null,t.ln=null,void(t.pos=null);t.line=e.getLine(t.ln),t.pos=t.dir>0?0:t.line.length-1}else t.pos+=t.dir}function a(e,t,n,r){var i=e.getLine(t),a=""===i,l={line:i,ln:t,pos:n,dir:r},s={ln:l.ln,pos:l.pos},c=""===l.line;for(o(e,l);null!==l.line;){if(s.ln=l.ln,s.pos=l.pos,""===l.line&&!c)return{ln:l.ln,pos:l.pos};if(a&&""!==l.line&&!S(l.line[l.pos]))return{ln:l.ln,pos:l.pos};!L(l.line[l.pos])||a||l.pos!==l.line.length-1&&!S(l.line[l.pos+1])||(a=!0),o(e,l)}var i=e.getLine(s.ln);s.pos=0;for(var u=i.length-1;u>=0;--u)if(!S(i[u])){s.pos=u;break}return s}function l(e,t,n,r){var i=e.getLine(t),a={line:i,ln:t,pos:n,dir:r},l={ln:a.ln,pos:null},s=""===a.line;for(o(e,a);null!==a.line;){if(""===a.line&&!s)return null!==l.pos?l:{ln:a.ln,pos:a.pos};if(L(a.line[a.pos])&&null!==l.pos&&(a.ln!==l.ln||a.pos+1!==l.pos))return l;""===a.line||S(a.line[a.pos])||(s=!1,l={ln:a.ln,pos:a.pos}),o(e,a)}var i=e.getLine(l.ln);l.pos=0;for(var c=0;c0;)s=i<0?l(e,s.ln,s.pos,i):a(e,s.ln,s.pos,i),n--;return r(s.ln,s.pos)}(e,t,n.repeat,i)},moveByScroll:function(e,t,n,r){var i=e.getScrollInfo(),o=null,a=n.repeat;a||(a=i.clientHeight/(2*e.defaultTextHeight()));var l=e.charCoords(t,"local");n.repeat=a;var o=V.moveByDisplayLines(e,t,n,r);if(!o)return null;var s=e.charCoords(o,"local");return e.scrollTo(null,i.top+s.top-l.top),o},moveByWords:function(e,t,n){return function(e,t,n,i,o,a){var l=ee(t),s=[];(i&&!o||!i&&o)&&n++;for(var c=!(i&&o),u=0;u0)f.index=0;else{var m=f.lineText.length;f.index=m>0?m-1:0}f.nextCh=f.lineText.charAt(f.index)}p(f)&&(o.line=c,o.ch=f.index,t--)}return f.nextCh||f.curMoveThrough?r(c,f.index):o}(e,i,n.forward,n.selectedCharacter)||t},moveToColumn:function(e,t,n,i){var o=n.repeat;return i.lastHPos=o-1,i.lastHSPos=e.charCoords(t,"div").left,function(e,t){var n=e.getCursor().line;return X(e,r(n,t-1))}(e,o)},moveToEol:function(e,t,n,i){var o=t;i.lastHPos=1/0;var a=r(o.line+n.repeat-1,1/0),l=e.clipPos(a);return l.ch--,i.lastHSPos=e.charCoords(l,"div").left,a},moveToFirstNonWhiteSpaceCharacter:function(e,t){var n=t;return r(n.line,me(e.getLine(n.line)))},moveToMatchedSymbol:function(e,t){for(var n,i=t,o=i.line,a=i.ch,l=e.getLine(o);aa.ch||o.line>a.line){var f=o;o=a,a=f}return i?a.ch+=1:o.ch+=1,{start:o,end:a}}(e,t,o,l);else if({"'":!0,'"':!0}[o])a=function(e,t,n,i){var o,a,l,s,c=ee(t),u=e.getLine(c.line).split(""),f=u.indexOf(n);if(c.ch-1&&!o;l--)u[l]==n&&(o=l+1);else o=c.ch+1;if(o&&!a)for(l=o,s=u.length;lt.lastLine()&&n.linewise&&!p?t.replaceRange("",h,u):t.replaceRange("",c,u),n.linewise&&(p||(t.setCursor(h),e.commands.newlineAndIndent(t)),c.ch=Number.MAX_VALUE),o=c}N.registerController.pushText(n.registerName,"change",a,n.linewise,i.length>1),G.enterInsertMode(t,{head:o},t.state.vim)},delete:function(e,t,n){var i,o,a=e.state.vim;if(a.visualBlock){o=e.getSelection();var l=q("",n.length);e.replaceSelections(l),i=n[0].anchor}else{var s=n[0].anchor,c=n[0].head;t.linewise&&c.line!=e.firstLine()&&s.line==e.lastLine()&&s.line==c.line-1&&(s.line==e.firstLine()?s.ch=0:s=r(s.line-1,ae(e,s.line-1))),o=e.getRange(s,c),e.replaceRange("",s,c),i=s,t.linewise&&(i=V.moveToFirstNonWhiteSpaceCharacter(e,s))}N.registerController.pushText(t.registerName,"delete",o,t.linewise,a.visualBlock);var u=a.insertMode;return X(e,i,u)},indent:function(e,t,n){var r=e.state.vim,i=n[0].anchor.line,o=r.visualBlock?n[n.length-1].anchor.line:n[0].head.line,a=r.visualMode?t.repeat:1;t.linewise&&o--;for(var l=i;l<=o;l++)for(var s=0;sc.top?(s.line+=(l-c.top)/i,s.line=Math.ceil(s.line),e.setCursor(s),c=e.charCoords(s,"local"),e.scrollTo(null,c.top)):e.scrollTo(null,l);else{var u=l+e.getScrollInfo().clientHeight;u=a.anchor.line?Z(a.head,0,1):r(a.anchor.line,0);else if("inplace"==o&&i.visualMode)return;t.setOption("disableInput",!1),n&&n.replace?(t.toggleOverwrite(!0),t.setOption("keyMap","vim-replace"),e.signal(t,"vim-mode-change",{mode:"replace"})):(t.toggleOverwrite(!1),t.setOption("keyMap","vim-insert"),e.signal(t,"vim-mode-change",{mode:"insert"})),N.macroModeState.isPlaying||(t.on("change",Xe),e.on(t.getInputField(),"keydown",Qe)),i.visualMode&&pe(t),ue(t,l,s)}},toggleVisualMode:function(t,n,i){var o,a=n.repeat,l=t.getCursor();i.visualMode?i.visualLine^n.linewise||i.visualBlock^n.blockwise?(i.visualLine=!!n.linewise,i.visualBlock=!!n.blockwise,e.signal(t,"vim-mode-change",{mode:"visual",subMode:i.visualLine?"linewise":i.visualBlock?"blockwise":""}),de(t)):pe(t):(i.visualMode=!0,i.visualLine=!!n.linewise,i.visualBlock=!!n.blockwise,o=X(t,r(l.line,l.ch+a-1),!0),i.sel={anchor:l,head:o},e.signal(t,"vim-mode-change",{mode:"visual",subMode:i.visualLine?"linewise":i.visualBlock?"blockwise":""}),de(t),Ce(t,i,"<",re(l,o)),Ce(t,i,">",ie(l,o)))},reselectLastSelection:function(t,n,r){var i=r.lastSelection;if(r.visualMode&&fe(t,r),i){var o=i.anchorMark.find(),a=i.headMark.find();if(!o||!a)return;r.sel={anchor:o,head:a},r.visualMode=!0,r.visualLine=i.visualLine,r.visualBlock=i.visualBlock,de(t),Ce(t,r,"<",re(o,a)),Ce(t,r,">",ie(o,a)),e.signal(t,"vim-mode-change",{mode:"visual",subMode:r.visualLine?"linewise":r.visualBlock?"blockwise":""})}},joinLines:function(e,t,n){var i,o;if(n.visualMode){if(i=e.getCursor("anchor"),ne(o=e.getCursor("head"),i)){var a=o;o=i,i=a}o.ch=ae(e,o.line)-1}else{var l=Math.max(t.repeat,2);i=e.getCursor(),o=X(e,r(i.line+l-1,1/0))}for(var s=0,c=i.line;c1)var a=Array(t.repeat+1).join(a);var p,m,g=o.linewise,v=o.blockwise;if(g)n.visualMode?a=n.visualLine?a.slice(0,-1):"\n"+a.slice(0,a.length-1)+"\n":t.after?(a="\n"+a.slice(0,a.length-1),i.ch=ae(e,i.line)):i.ch=0;else{if(v){a=a.split("\n");for(var y=0;ye.lastLine()&&e.replaceRange("\n",r(M,0));var T=ae(e,M);Tu.length&&(o=u.length),a=r(s.line,o)}if("\n"==l)i.visualMode||t.replaceRange("",s,a),(e.commands.newlineAndIndentContinueComment||e.commands.newlineAndIndent)(t);else{var f=t.getRange(s,a);if(f=f.replace(/[^\n]/g,l),i.visualBlock){var d=new Array(t.getOption("tabSize")+1).join(" ");f=(f=t.getSelection()).replace(/\t/g,d).replace(/[^\n]/g,l).split("\n"),t.replaceSelections(f)}else t.replaceRange(f,s,a);i.visualMode?(s=ne(c[0].anchor,c[0].head)?c[0].anchor:c[0].head,t.setCursor(s),pe(t,!1)):t.setCursor(Z(a,0,-1))}},incrementNumberToken:function(e,t){for(var n,i,o,a,l=e.getCursor(),s=e.getLine(l.line),c=/(-?)(?:(0x)([\da-f]+)|(0b|0|)(\d+))/gi;null!==(n=c.exec(s))&&(i=n.index,o=i+n[0].length,!(l.ch"==t.slice(-11)){var n=t.length-11,r=e.slice(0,n),i=t.slice(0,n);return r==i&&e.length>n?"full":0==i.indexOf(r)&&"partial"}return e==t?"full":0==t.indexOf(e)&&"partial"}function Q(e,t,n){return function(){for(var r=0;r2&&(t=re.apply(void 0,Array.prototype.slice.call(arguments,1))),ne(e,t)?e:t}function ie(e,t){return arguments.length>2&&(t=ie.apply(void 0,Array.prototype.slice.call(arguments,1))),ne(e,t)?t:e}function oe(e,t,n){var r=ne(e,t),i=ne(t,n);return r&&i}function ae(e,t){return e.getLine(t).length}function le(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}function se(e,t,n){var i=ae(e,t),o=new Array(n-i+1).join(" ");e.setCursor(r(t,i)),e.replaceRange(o,e.getCursor())}function ce(e,t){var n=[],i=e.listSelections(),o=ee(e.clipPos(t)),a=!te(t,o),l=e.getCursor("head"),s=function(e,t,n){for(var r=0;rs?u:0,d=i[f].anchor,h=Math.min(d.line,o.line),p=Math.max(d.line,o.line),m=d.ch,g=o.ch,v=i[f].head.ch-m,y=g-m;v>0&&y<=0?(m++,a||g--):v<0&&y>=0?(m--,c||g++):v<0&&-1==y&&(m--,g++);for(var b=h;b<=p;b++){var x={anchor:new r(b,m),head:new r(b,g)};n.push(x)}return e.setSelections(n),t.ch=g,d.ch=m,d}function ue(e,t,n){for(var r=[],i=0;ic&&(o.line=c),o.ch=ae(e,o.line)}return{ranges:[{anchor:a,head:o}],primary:0}}if("block"==n){for(var u=Math.min(a.line,o.line),f=Math.min(a.ch,o.ch),d=Math.max(a.line,o.line),h=Math.max(a.ch,o.ch)+1,p=d-u+1,m=o.line==u?0:p-1,g=[],v=0;v=l.length)return null;i?c=p[0]:(c=h[0])(l.charAt(s))||(c=h[1]);for(var u=s,f=s;c(l.charAt(u))&&u=0;)f--;if(f++,t){for(var d=u;/\s/.test(l.charAt(u))&&u0;)f--;f||(f=m)}}return{start:r(a.line,f),end:r(a.line,u)}}function ve(e,t,n){te(t,n)||N.jumpList.add(e,t,n)}function ye(e,t){N.lastCharacterSearch.increment=e,N.lastCharacterSearch.forward=t.forward,N.lastCharacterSearch.selectedCharacter=t.selectedCharacter}var be={"(":"bracket",")":"bracket","{":"bracket","}":"bracket","[":"section","]":"section","*":"comment","/":"comment",m:"method",M:"method","#":"preprocess"},xe={bracket:{isComplete:function(e){if(e.nextCh===e.symb){if(e.depth++,e.depth>=1)return!0}else e.nextCh===e.reverseSymb&&e.depth--;return!1}},section:{init:function(e){e.curMoveThrough=!0,e.symb=(e.forward?"]":"[")===e.symb?"{":"}"},isComplete:function(e){return 0===e.index&&e.nextCh===e.symb}},comment:{isComplete:function(e){var t="*"===e.lastCh&&"/"===e.nextCh;return e.lastCh=e.nextCh,t}},method:{init:function(e){e.symb="m"===e.symb?"{":"}",e.reverseSymb="{"===e.symb?"}":"{"},isComplete:function(e){return e.nextCh===e.symb}},preprocess:{init:function(e){e.index=0},isComplete:function(e){if("#"===e.nextCh){var t=e.lineText.match(/#(\w+)/)[1];if("endif"===t){if(e.forward&&0===e.depth)return!0;e.depth++}else if("if"===t){if(!e.forward&&0===e.depth)return!0;e.depth--}if("else"===t&&0===e.depth)return!0}return!1}}};function we(e,t,n,r,i){var o=t.line,a=t.ch,l=e.getLine(o),s=n?1:-1,c=r?p:h;if(i&&""==l){if(o+=s,l=e.getLine(o),!w(e,o))return null;a=n?0:l.length}for(;;){if(i&&""==l)return{from:0,to:0,line:o};for(var u=s>0?l.length:-1,f=u,d=u;a!=u;){for(var m=!1,g=0;g0?0:l.length}}function ke(e,t,n,i){for(var o,a=e.getCursor(),l=a.ch,s=0;s0;)d(u,i)&&n--,u+=i;return new r(u,0)}var h=e.state.vim;if(h.visualLine&&d(l,1,!0)){var p=h.sel.anchor;d(p.line,-1,!0)&&(o&&p.line==l||(l+=1))}var m=f(l);for(u=l;u<=c&&n;u++)d(u,1,!0)&&(o&&f(u)==m||n--);for(a=new r(u,0),u>c&&!m?m=!0:o=!1,u=l;u>s&&(o&&f(u)!=m&&u!=l||!d(u,-1,!0));u--);return{start:new r(u,0),end:a}}function Me(){}function Te(e){var t=e.state.vim;return t.searchState_||(t.searchState_=new Me)}function Ae(e,t,n,r,i){e.openDialog?e.openDialog(t,r,{bottom:!0,value:i.value,onKeyDown:i.onKeyDown,onKeyUp:i.onKeyUp,selectValueOnOpen:!1}):r(prompt(n,""))}function Oe(e,t){var n=Ee(e,t)||[];if(!n.length)return[];var r=[];if(0===n[0]){for(var i=0;i'+t+"",{bottom:!0,duration:5e3}):alert(t)}var Be="(Javascript regexp)";function De(e,t){var n,r,i,o=(t.prefix||"")+" "+(t.desc||""),a=(n=t.prefix,r=t.desc,i=''+(n||"")+'',r&&(i+=' '+r+""),i);Ae(e,a,o,t.onClose,t)}function Fe(e,t,n,r){if(t){var i=Te(e),o=Ie(t,!!n,!!r);if(o)return We(e,o),function(e,t){if(e instanceof RegExp&&t instanceof RegExp){for(var n=["global","multiline","ignoreCase","source"],r=0;r0;t--){var n=e.substring(0,t);if(this.commandMap_[n]){var r=this.commandMap_[n];if(0===r.name.indexOf(e))return r}}return null},buildCommandMap_:function(){this.commandMap_={};for(var e=0;e
";if(n){n=n.join("");for(var o=0;o"}}else for(var l in r){var s=r[l].toString();s.length&&(i+='"'+l+" "+s+"
")}Re(e,i)},sort:function(t,n){var i,o,a,l,s,c=function(){if(n.argString){var t=new e.StringStream(n.argString);if(t.eat("!")&&(i=!0),t.eol())return;if(!t.eatSpace())return"Invalid arguments";var r=t.match(/([dinuox]+)?\s*(\/.+\/)?\s*/);if(!r&&!t.eol())return"Invalid arguments";if(r[1]){o=-1!=r[1].indexOf("i"),a=-1!=r[1].indexOf("u");var c=-1!=r[1].indexOf("d")||-1!=r[1].indexOf("n")&&1,u=-1!=r[1].indexOf("x")&&1,f=-1!=r[1].indexOf("o")&&1;if(c+u+f>1)return"Invalid arguments";l=(c?"decimal":u&&"hex")||f&&"octal"}r[2]&&(s=new RegExp(r[2].substr(1,r[2].length-2),o?"i":""))}}();if(c)Re(t,c+": "+n.argString);else{var u=n.line||t.firstLine(),f=n.lineEnd||n.line||t.lastLine();if(u!=f){var d=r(u,0),h=r(f,ae(t,f)),p=t.getRange(d,h).split("\n"),m=s||("decimal"==l?/(-?)([\d]+)/:"hex"==l?/(-?)(?:0x)?([0-9a-f]+)/i:"octal"==l?/([0-7]+)/:null),g="decimal"==l?10:"hex"==l?16:"octal"==l?8:null,v=[],y=[];if(l||s)for(var b=0;b")}if(r){var h=0,p=function(){if(h=n&&e<=l:e==n);)if(r||!f||a.from().line!=f.line)return t.scrollIntoView(a.from(),30),t.setSelection(a.from(),a.to()),f=a.from(),void(u=!1);var e,n,l;u=!0}function m(e){if(e&&e(),t.focus(),f){t.setCursor(f);var n=t.state.vim;n.exMode=!1,n.lastHPos=n.lastHSPos=f.ch}c&&c()}if(p(),!u)return n?void De(t,{prefix:"replace with "+s+" (y/n/a/q/l)",onKeyDown:function(n,r,i){switch(e.e_stop(n),e.keyName(n)){case"Y":h(),p();break;case"N":p();break;case"A":var o=c;c=void 0,t.operation(d),c=o;break;case"L":h();case"Q":case"Esc":case"Ctrl-C":case"Ctrl-[":m(i)}return u&&m(i),!0}}):(d(),void(c&&c()));Re(t,"No matches for "+l.source)}(t,f,h,g,v,b,m,u,n.callback)}else Re(t,"No previous substitute regular expression")},redo:e.commands.redo,undo:e.commands.undo,write:function(t){e.commands.save?e.commands.save(t):t.save&&t.save()},nohlsearch:function(e){_e(e)},yank:function(e){var t=ee(e.getCursor()),n=t.line,r=e.getLine(n);N.registerController.pushText("0","yank",r,!0,!0)},delmarks:function(t,n){if(n.argString&&le(n.argString))for(var r=t.state.vim,i=new e.StringStream(le(n.argString));!i.eol();){i.eatSpace();var o=i.pos;if(!i.match(/[a-zA-Z]/,!1))return void Re(t,"Invalid argument: "+n.argString.substring(o));var a=i.next();if(i.match("-",!0)){if(!i.match(/[a-zA-Z]/,!1))return void Re(t,"Invalid argument: "+n.argString.substring(o));var l=a,s=i.next();if(!(k(l)&&k(s)||C(l)&&C(s)))return void Re(t,"Invalid argument: "+l+"-");var c=l.charCodeAt(0),u=s.charCodeAt(0);if(c>=u)return void Re(t,"Invalid argument: "+n.argString.substring(o));for(var f=0;f<=u-c;f++){var d=String.fromCharCode(c+f);delete r.marks[d]}}else delete r.marks[a]}else Re(t,"Argument required")}},Ve=new je;function qe(t){var n=t.state.vim,r=N.macroModeState,i=N.registerController.getRegister("."),o=r.isPlaying,a=r.lastInsertModeChanges,l=[];if(!o){for(var s=a.inVisualBlock&&n.lastSelection?n.lastSelection.visualBlock.height:1,c=a.changes,l=[],u=0;u1&&(et(t,n,n.insertModeRepeat-1,!0),n.lastEditInputState.repeatOverride=n.insertModeRepeat),delete n.insertModeRepeat,n.insertMode=!1,t.setCursor(t.getCursor().line,t.getCursor().ch-1),t.setOption("keyMap","vim"),t.setOption("disableInput",!0),t.toggleOverwrite(!1),i.setText(a.changes.join("")),e.signal(t,"vim-mode-change",{mode:"normal"}),r.isRecording&&function(e){if(!e.isPlaying){var t=e.latestRegister,n=N.registerController.getRegister(t);n&&n.pushInsertModeChanges&&n.pushInsertModeChanges(e.lastInsertModeChanges)}}(r)}function $e(e){t.unshift(e)}function Ge(t,n,r,i){var o=N.registerController.getRegister(i);if(":"==i)return o.keyBuffer[0]&&Ve.processCommand(t,o.keyBuffer[0]),void(r.isPlaying=!1);var a=o.keyBuffer,l=0;r.isPlaying=!0,r.replaySearchQueries=o.searchQueries.slice(0);for(var s=0;s|<\w+>|./.exec(f),u=c[0],f=f.substring(c.index+u.length),e.Vim.handleKey(t,u,"macro"),n.insertMode){var d=o.insertModeChanges[l++].changes;N.macroModeState.lastInsertModeChanges.changes=d,tt(t,d,1),qe(t)}r.isPlaying=!1}function Xe(e,t){var n=N.macroModeState,r=n.lastInsertModeChanges;if(!n.isPlaying)for(;t;){if(r.expectCursorActivityForChange=!0,"+input"==t.origin||"paste"==t.origin||void 0===t.origin){var i=t.text.join("\n");r.maybeReset&&(r.changes=[],r.maybeReset=!1),e.state.overwrite&&!/\n/.test(i)?r.changes.push([i]):r.changes.push(i)}t=t.next}}function Ye(t){var n=t.state.vim;if(n.insertMode){var r=N.macroModeState;if(r.isPlaying)return;var i=r.lastInsertModeChanges;i.expectCursorActivityForChange?i.expectCursorActivityForChange=!1:i.maybeReset=!0}else t.curOp.isVimOp||function(t,n){var r=t.getCursor("anchor"),i=t.getCursor("head");if(n.visualMode&&!t.somethingSelected()?pe(t,!1):n.visualMode||n.insertMode||!t.somethingSelected()||(n.visualMode=!0,n.visualLine=!1,e.signal(t,"vim-mode-change",{mode:"visual"})),n.visualMode){var o=ne(i,r)?0:-1,a=ne(i,r)?-1:0;i=Z(i,0,o),r=Z(r,0,a),n.sel={anchor:r,head:i},Ce(t,n,"<",re(i,r)),Ce(t,n,">",ie(i,r))}else n.insertMode||(n.lastHPos=t.getCursor().ch)}(t,n);n.visualMode&&Ze(t)}function Ze(e){var t=e.state.vim,n=X(e,ee(t.sel.head)),r=Z(n,0,1);t.fakeCursor&&t.fakeCursor.clear(),t.fakeCursor=e.markText(n,r,{className:"cm-animate-fat-cursor"})}function Je(e){this.keyName=e}function Qe(t){var n=N.macroModeState,r=n.lastInsertModeChanges,i=e.keyName(t);i&&(-1==i.indexOf("Delete")&&-1==i.indexOf("Backspace")||e.lookupKey(i,"vim-insert",function(){return r.maybeReset&&(r.changes=[],r.maybeReset=!1),r.changes.push(new Je(i)),!0}))}function et(e,t,n,r){var i=N.macroModeState;i.isPlaying=!0;var o=!!t.lastEditActionCommand,a=t.inputState;function l(){o?U.processAction(e,t,t.lastEditActionCommand):U.evalInput(e,t)}function s(n){if(i.lastInsertModeChanges.changes.length>0){n=t.lastEditActionCommand?n:1;var r=i.lastInsertModeChanges;tt(e,r.changes,n)}}if(t.inputState=t.lastEditInputState,o&&t.lastEditActionCommand.interlaceInsertRepeat)for(var c=0;c50&&r.shift()}function o(e){return r[r.length-(e?Math.min(e,1):1)]||""}var a=null;function l(e,t,o,l,s){null==s&&(s=e.getRange(t,o)),"grow"==l&&a&&a.cm==e&&n(t,a.pos)&&e.isClean(a.gen)?function(e){if(!r.length)return i(e);r[r.length-1]+=e}(s):!1!==l&&i(s),e.replaceRange("",t,o,"+delete"),a="grow"==l?{cm:e,pos:t,gen:e.changeGeneration()}:null}function s(e,t,n){return e.findPosH(t,n,"char",!0)}function c(e,t,n){return e.findPosH(t,n,"word",!0)}function u(e,t,n){return e.findPosV(t,n,"line",e.doc.sel.goalColumn)}function f(e,t,n){return e.findPosV(t,n,"page",e.doc.sel.goalColumn)}function d(e,n,r){for(var i=n.line,o=e.getLine(i),a=/\S/.test(r<0?o.slice(0,n.ch):o.slice(n.ch)),l=e.firstLine(),s=e.lastLine();;){if((i+=r)s)return e.clipPos(t(i-r,r<0?0:null));o=e.getLine(i);var c=/\S/.test(o);if(c)a=!0;else if(a)return t(i,0)}}function h(e,n,r){for(var i=n.line,o=n.ch,a=e.getLine(n.line),l=!1;;){var s=a.charAt(o+(r<0?-1:0));if(s){if(l&&/[!?.]/.test(s))return t(i,o+(r>0?1:0));l||(l=/\w/.test(s)),o+=r}else{if(i==(r<0?e.firstLine():e.lastLine()))return t(i,o);if(a=e.getLine(i+r),!/\S/.test(a))return t(i,o);i+=r,o=r<0?a.length:0}}}function p(e,r,i){var o;if(e.findMatchingBracket&&(o=e.findMatchingBracket(r,{strict:!0}))&&o.match&&(o.forward?1:-1)==i)return i>0?t(o.to.line,o.to.ch+1):o.to;for(var a=!0;;a=!1){var l=e.getTokenAt(r),s=t(r.line,i<0?l.start:l.end);if(!(a&&i>0&&l.end==r.ch)&&/\w/.test(l.string))return s;var c=e.findPosH(s,i,"char");if(n(s,c))return r;r=c}}function m(e,t){var n=e.state.emacsPrefix;return n?(S(e),"-"==n?-1:Number(n)):t?null:1}function g(e){var t="string"==typeof e?function(t){t.execCommand(e)}:e;return function(e){var n=m(e);t(e);for(var r=1;r1&&"+input"==t.origin){for(var r=t.text.join("\n"),i="",o=1;o1&&r.pop(),o()),"around","paste")},"Ctrl-Space":T,"Ctrl-Shift-2":T,"Ctrl-F":y(s,1),"Ctrl-B":y(s,-1),Right:y(s,1),Left:y(s,-1),"Ctrl-D":function(e){b(e,s,1,!1)},Delete:function(e){x(e,!1)||b(e,s,1,!1)},"Ctrl-H":function(e){b(e,s,-1,!1)},Backspace:function(e){x(e,!1)||b(e,s,-1,!1)},"Alt-F":y(c,1),"Alt-B":y(c,-1),"Alt-Right":y(c,1),"Alt-Left":y(c,-1),"Alt-D":function(e){b(e,c,1,"grow")},"Alt-Backspace":function(e){b(e,c,-1,"grow")},"Ctrl-N":y(u,1),"Ctrl-P":y(u,-1),Down:y(u,1),Up:y(u,-1),"Ctrl-A":"goLineStart","Ctrl-E":"goLineEnd",End:"goLineEnd",Home:"goLineStart","Alt-V":y(f,-1),"Ctrl-V":y(f,1),PageUp:y(f,-1),PageDown:y(f,1),"Ctrl-Up":y(d,-1),"Ctrl-Down":y(d,1),"Alt-A":y(h,-1),"Alt-E":y(h,1),"Alt-K":function(e){b(e,h,1,"grow")},"Ctrl-Alt-K":function(e){b(e,p,1,"grow")},"Ctrl-Alt-Backspace":function(e){b(e,p,-1,"grow")},"Ctrl-Alt-F":y(p,1),"Ctrl-Alt-B":y(p,-1),"Shift-Ctrl-Alt-2":function(e){var t=e.getCursor();e.setSelection(v(e,t,p,1),t)},"Ctrl-Alt-T":function(e){var t=p(e,e.getCursor(),-1),n=p(e,t,1),r=p(e,n,1),i=p(e,r,-1);e.replaceRange(e.getRange(i,r)+e.getRange(n,i)+e.getRange(t,n),t,r)},"Ctrl-Alt-U":g(function(e){for(var n=e.getCursor(),r=n.line,i=n.ch,o=[];r>=e.firstLine();){for(var a=e.getLine(r),l=null==i?a.length:i;l>0;){var i=a.charAt(--l);if(")"==i)o.push("(");else if("]"==i)o.push("[");else if("}"==i)o.push("{");else if(/[\(\{\[]/.test(i)&&(!o.length||o.pop()!=i))return e.extendSelection(t(r,l))}--r,i=null}}),"Alt-Space":function(e){for(var n=e.getCursor(),r=n.ch,i=n.ch,o=e.getLine(n.line);r&&/\s/.test(o.charAt(r-1));)--r;for(;i0)return e.setCursor(t-1);!function(e,t,n){e.openDialog?e.openDialog(t+': ',n,{bottom:!0}):n(prompt(t,""))}(e,"Goto line",function(t){var n;t&&!isNaN(n=Number(t))&&n==(0|n)&&n>0&&e.setCursor(n-1)})},"Ctrl-X Tab":function(e){e.indentSelection(m(e,!0)||e.getOption("indentUnit"))},"Ctrl-X Ctrl-X":function(e){e.setSelection(e.getCursor("head"),e.getCursor("anchor"))},"Ctrl-X Ctrl-S":"save","Ctrl-X Ctrl-W":"save","Ctrl-X S":"saveAll","Ctrl-X F":"open","Ctrl-X U":g("undo"),"Ctrl-X K":"close","Ctrl-X Delete":function(e){l(e,e.getCursor(),h(e,e.getCursor(),1),"grow")},"Ctrl-X H":"selectAll","Ctrl-Q Tab":g("insertTab"),"Ctrl-U":function(e){e.state.emacsPrefixMap=!0,e.addKeyMap(N),e.on("keyHandled",M),e.on("inputRead",M)}}),N={"Ctrl-G":S};function P(e){N[e]=function(t){w(t,e)},E["Ctrl-"+e]=function(t){w(t,e)},k["Ctrl-"+e]=!0}for(var I=0;I<10;++I)P(String(I));P("-")}(n(0))},function(e,t,n){var r;(r=n(0)).defineOption("showTrailingSpace",!1,function(e,t,n){n==r.Init&&(n=!1),n&&!t?e.removeOverlay("trailingspace"):!n&&t&&e.addOverlay({token:function(e){for(var t=e.string.length,n=t;n&&/\s/.test(e.string.charAt(n-1));--n);return n>e.pos?(e.pos=n,null):(e.pos=t,"trailingspace")},name:"trailingspace"})})},function(e,t,n){!function(e){"use strict";var t="CodeMirror-activeline",n="CodeMirror-activeline-background",r="CodeMirror-activeline-gutter";function i(e){for(var i=0;i>u",">>s",">=","<=","==","!=","=s",">=u",">s",">u","<",">","=","&","|","^","!"]);function l(e,t){var n;for(t.commentDepth=1;null!=(n=e.next());){if("*"===n&&e.eat("/")&&0==--t.commentDepth)return t.tokenize=null,"comment";"/"===n&&e.eat("*")&&t.commentDepth++}return"comment"}function s(e,t){for(var n,r=t.commentState;null!=(n=e.next());)if(0===r&&"t"===n)r=1;else if(1===r&&":"===n)return t.tokenize=null,t.commentState=0,r=2,"comment";return t.commentState=r,"comment"}return{startState:function(){return{tokenize:null,commentState:0,commentDepth:0}},token:function(n,c){if(n.eatSpace())return null;var u=(c.tokenize||function(n,c){var u,f=n.next();if("$"===f)return n.eatWhile(t),"variable";if("@"===f)return n.eatWhile(t),"meta";if('"'===f)return c.tokenize=(u=f,function(e,t){for(var n,r=!1;null!=(n=e.next());){if(n==u&&!r)return t.tokenize=null,"string";r=!r&&"\\"===n}return"string"}),c.tokenize(n,c);if("/"==f){if(n.eat("*"))return c.tokenize=l,l(n,c);if(n.eat("/"))return n.skipToEnd(),"comment"}if(/\d/.test(f)||("-"===f||"+"===f)&&/\d/.test(n.peek()))return n.eatWhile(/[\w\._\-+]/),"number";if(/[\[\]\(\)\{\},:]/.test(f))return null;if(o.test(f))return"operator";n.eatWhile(t);var d=n.current();if(d in a)return"operator";if(d in e)return"keyword";if(d in i){if(!n.eat(":"))return"builtin";n.eatWhile(t),d=n.current()}return d in r?"builtin":"Temporary"===d?(c.tokenize=s,c.tokenize(n,c)):null})(n,c);return u}}}),e.registerHelper("wordChars","wasm",t),e.defineMIME("text/wasm","wasm")})?r.apply(t,i):r)||(e.exports=o)},function(e,t,n){!function(e){"use strict";function t(e,t,n,r,i,o){this.indented=e,this.column=t,this.type=n,this.info=r,this.align=i,this.prev=o}function n(e,n,r,i){var o=e.indented;return e.context&&"statement"==e.context.type&&"statement"!=r&&(o=e.context.indented),e.context=new t(o,n,r,i,null,e.context)}function r(e){var t=e.context.type;return")"!=t&&"]"!=t&&"}"!=t||(e.indented=e.context.indented),e.context=e.context.prev}function i(e,t,n){return"variable"==t.prevToken||"type"==t.prevToken||!!/\S(?:[^- ]>|[*\]])\s*$|\*$/.test(e.string.slice(0,n))||!(!t.typeAtEndOfLine||e.column()!=e.indentation())||void 0}function o(e){for(;;){if(!e||"top"==e.type)return!0;if("}"==e.type&&"namespace"!=e.prev.info)return!1;e=e.prev}}function a(e){for(var t={},n=e.split(" "),r=0;r!?|\/]/,O=s.isIdentifierChar||/[\w\$_\xa1-\uffff]/;function E(e,t){var n,r=e.next();if(x[r]){var i=x[r](e,t);if(!1!==i)return i}if('"'==r||"'"==r)return t.tokenize=(n=r,function(e,t){for(var r,i=!1,o=!1;null!=(r=e.next());){if(r==n&&!i){o=!0;break}i=!i&&"\\"==r}return(o||!i&&!w)&&(t.tokenize=null),"string"}),t.tokenize(e,t);if(L.test(r))return c=r,null;if(M.test(r)){if(e.backUp(1),e.match(T))return"number";e.next()}if("/"==r){if(e.eat("*"))return t.tokenize=N,N(e,t);if(e.eat("/"))return e.skipToEnd(),"comment"}if(A.test(r)){for(;!e.match(/^\/[\/*]/,!1)&&e.eat(A););return"operator"}if(e.eatWhile(O),S)for(;e.match(S);)e.eatWhile(O);var o=e.current();return l(p,o)?(l(v,o)&&(c="newstatement"),l(y,o)&&(u=!0),"keyword"):l(m,o)?"type":l(g,o)?(l(v,o)&&(c="newstatement"),"builtin"):l(b,o)?"atom":"variable"}function N(e,t){for(var n,r=!1;n=e.next();){if("/"==n&&r){t.tokenize=null;break}r="*"==n}return"comment"}function P(e,t){s.typeFirstDefinitions&&e.eol()&&o(t.context)&&(t.typeAtEndOfLine=i(e,t,e.pos))}return{startState:function(e){return{tokenize:null,context:new t((e||0)-f,0,"top",null,!1),indented:0,startOfLine:!0,prevToken:null}},token:function(e,t){var a=t.context;if(e.sol()&&(null==a.align&&(a.align=!1),t.indented=e.indentation(),t.startOfLine=!0),e.eatSpace())return P(e,t),null;c=u=null;var l=(t.tokenize||E)(e,t);if("comment"==l||"meta"==l)return l;if(null==a.align&&(a.align=!0),";"==c||":"==c||","==c&&e.match(/^\s*(?:\/\/.*)?$/,!1))for(;"statement"==t.context.type;)r(t);else if("{"==c)n(t,e.column(),"}");else if("["==c)n(t,e.column(),"]");else if("("==c)n(t,e.column(),")");else if("}"==c){for(;"statement"==a.type;)a=r(t);for("}"==a.type&&(a=r(t));"statement"==a.type;)a=r(t)}else c==a.type?r(t):k&&(("}"==a.type||"top"==a.type)&&";"!=c||"statement"==a.type&&"newstatement"==c)&&n(t,e.column(),"statement",e.current());if("variable"==l&&("def"==t.prevToken||s.typeFirstDefinitions&&i(e,t,e.start)&&o(t.context)&&e.match(/^\s*\(/,!1))&&(l="def"),x.token){var f=x.token(e,t,l);void 0!==f&&(l=f)}return"def"==l&&!1===s.styleDefs&&(l="variable"),t.startOfLine=!1,t.prevToken=u?"def":l||c,P(e,t),l},indent:function(t,n){if(t.tokenize!=E&&null!=t.tokenize||t.typeAtEndOfLine)return e.Pass;var r=t.context,i=n&&n.charAt(0);if("statement"==r.type&&"}"==i&&(r=r.prev),s.dontIndentStatements)for(;"statement"==r.type&&s.dontIndentStatements.test(r.info);)r=r.prev;if(x.indent){var o=x.indent(t,r,n);if("number"==typeof o)return o}var a=i==r.type,l=r.prev&&"switch"==r.prev.info;if(s.allmanIndentation&&/[{(]/.test(i)){for(;"top"!=r.type&&"}"!=r.type;)r=r.prev;return r.indented}return"statement"==r.type?r.indented+("{"==i?0:d):!r.align||h&&")"==r.type?")"!=r.type||a?r.indented+(a?0:f)+(a||!l||/^(?:case|default)\b/.test(n)?0:f):r.indented+d:r.column+(a?0:1)},electricInput:C?/^\s*(?:case .*?:|default:|\{\}?|\})$/:/^\s*[{}]$/,blockCommentStart:"/*",blockCommentEnd:"*/",blockCommentContinue:" * ",lineComment:"//",fold:"brace"}});var s="auto if break case register continue return default do sizeof static else struct switch extern typedef union for goto while enum const volatile",c="int long char short double float unsigned signed void size_t ptrdiff_t";function u(e,t){if(!t.startOfLine)return!1;for(var n,r=null;n=e.peek();){if("\\"==n&&e.match(/^.$/)){r=u;break}if("/"==n&&e.match(/^\/[\/\*]/,!1))break;e.next()}return t.tokenize=r,"meta"}function f(e,t){return"type"==t.prevToken&&"type"}function d(e){return e.eatWhile(/[\w\.']/),"number"}function h(e,t){if(e.backUp(1),e.match(/(R|u8R|uR|UR|LR)/)){var n=e.match(/"([^\s\\()]{0,16})\(/);return!!n&&(t.cpp11RawStringDelim=n[1],t.tokenize=m,m(e,t))}return e.match(/(u8|u|U|L)/)?!!e.match(/["']/,!1)&&"string":(e.next(),!1)}function p(e,t){for(var n;null!=(n=e.next());)if('"'==n&&!e.eat('"')){t.tokenize=null;break}return"string"}function m(e,t){var n=t.cpp11RawStringDelim.replace(/[^\w\s]/g,"\\$&"),r=e.match(new RegExp(".*?\\)"+n+'"'));return r?t.tokenize=null:e.skipToEnd(),"string"}function g(t,n){"string"==typeof t&&(t=[t]);var r=[];function i(e){if(e)for(var t in e)e.hasOwnProperty(t)&&r.push(t)}i(n.keywords),i(n.types),i(n.builtin),i(n.atoms),r.length&&(n.helperType=t[0],e.registerHelper("hintWords",t[0],r));for(var o=0;o!?|\/#:@]/,hooks:{"@":function(e){return e.eatWhile(/[\w\$_]/),"meta"},'"':function(e,t){return!!e.match('""')&&(t.tokenize=v,t.tokenize(e,t))},"'":function(e){return e.eatWhile(/[\w\$_\xa1-\uffff]/),"atom"},"=":function(e,n){var r=n.context;return!("}"!=r.type||!r.align||!e.eat(">"))&&(n.context=new t(r.indented,r.column,r.type,r.info,null,r.prev),"operator")},"/":function(e,t){return!!e.eat("*")&&(t.tokenize=function e(t){return function(n,r){for(var i;i=n.next();){if("*"==i&&n.eat("/")){if(1==t){r.tokenize=null;break}return r.tokenize=e(t-1),r.tokenize(n,r)}if("/"==i&&n.eat("*"))return r.tokenize=e(t+1),r.tokenize(n,r)}return"comment"}}(1),t.tokenize(e,t))}},modeProps:{closeBrackets:{triples:'"'}}}),g("text/x-kotlin",{name:"clike",keywords:a("package as typealias class interface this super val operator var fun for is in This throw return annotation break continue object if else while do try when !in !is as? file import where by get set abstract enum open inner override private public internal protected catch finally out final vararg reified dynamic companion constructor init sealed field property receiver param sparam lateinit data inline noinline tailrec external annotation crossinline const operator infix suspend actual expect setparam"),types:a("Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable Compiler Double Exception Float Integer Long Math Number Object Package Pair Process Runtime Runnable SecurityManager Short StackTraceElement StrictMath String StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void Annotation Any BooleanArray ByteArray Char CharArray DeprecationLevel DoubleArray Enum FloatArray Function Int IntArray Lazy LazyThreadSafetyMode LongArray Nothing ShortArray Unit"),intendSwitch:!1,indentStatements:!1,multiLineStrings:!0,number:/^(?:0x[a-f\d_]+|0b[01_]+|(?:[\d_]+(\.\d+)?|\.\d+)(?:e[-+]?[\d_]+)?)(u|ll?|l|f)?/i,blockKeywords:a("catch class do else finally for if where try while enum"),defKeywords:a("class val var object interface fun"),atoms:a("true false null this"),hooks:{"@":function(e){return e.eatWhile(/[\w\$_]/),"meta"},'"':function(e,t){var n;return t.tokenize=(n=e.match('""'),function(e,t){for(var r,i=!1,o=!1;!e.eol();){if(!n&&!i&&e.match('"')){o=!0;break}if(n&&e.match('"""')){o=!0;break}r=e.next(),!i&&"$"==r&&e.match("{")&&e.skipTo("}"),i=!i&&"\\"==r&&!n}return!o&&n||(t.tokenize=null),"string"}),t.tokenize(e,t)}},modeProps:{closeBrackets:{triples:'"'}}}),g(["x-shader/x-vertex","x-shader/x-fragment"],{name:"clike",keywords:a("sampler1D sampler2D sampler3D samplerCube sampler1DShadow sampler2DShadow const attribute uniform varying break continue discard return for while do if else struct in out inout"),types:a("float int bool void vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 mat2 mat3 mat4"),blockKeywords:a("for while do if else struct"),builtin:a("radians degrees sin cos tan asin acos atan pow exp log exp2 sqrt inversesqrt abs sign floor ceil fract mod min max clamp mix step smoothstep length distance dot cross normalize ftransform faceforward reflect refract matrixCompMult lessThan lessThanEqual greaterThan greaterThanEqual equal notEqual any all not texture1D texture1DProj texture1DLod texture1DProjLod texture2D texture2DProj texture2DLod texture2DProjLod texture3D texture3DProj texture3DLod texture3DProjLod textureCube textureCubeLod shadow1D shadow2D shadow1DProj shadow2DProj shadow1DLod shadow2DLod shadow1DProjLod shadow2DProjLod dFdx dFdy fwidth noise1 noise2 noise3 noise4"),atoms:a("true false gl_FragColor gl_SecondaryColor gl_Normal gl_Vertex gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 gl_FogCoord gl_PointCoord gl_Position gl_PointSize gl_ClipVertex gl_FrontColor gl_BackColor gl_FrontSecondaryColor gl_BackSecondaryColor gl_TexCoord gl_FogFragCoord gl_FragCoord gl_FrontFacing gl_FragData gl_FragDepth gl_ModelViewMatrix gl_ProjectionMatrix gl_ModelViewProjectionMatrix gl_TextureMatrix gl_NormalMatrix gl_ModelViewMatrixInverse gl_ProjectionMatrixInverse gl_ModelViewProjectionMatrixInverse gl_TexureMatrixTranspose gl_ModelViewMatrixInverseTranspose gl_ProjectionMatrixInverseTranspose gl_ModelViewProjectionMatrixInverseTranspose gl_TextureMatrixInverseTranspose gl_NormalScale gl_DepthRange gl_ClipPlane gl_Point gl_FrontMaterial gl_BackMaterial gl_LightSource gl_LightModel gl_FrontLightModelProduct gl_BackLightModelProduct gl_TextureColor gl_EyePlaneS gl_EyePlaneT gl_EyePlaneR gl_EyePlaneQ gl_FogParameters gl_MaxLights gl_MaxClipPlanes gl_MaxTextureUnits gl_MaxTextureCoords gl_MaxVertexAttribs gl_MaxVertexUniformComponents gl_MaxVaryingFloats gl_MaxVertexTextureImageUnits gl_MaxTextureImageUnits gl_MaxFragmentUniformComponents gl_MaxCombineTextureImageUnits gl_MaxDrawBuffers"),indentSwitch:!1,hooks:{"#":u},modeProps:{fold:["brace","include"]}}),g("text/x-nesc",{name:"clike",keywords:a(s+"as atomic async call command component components configuration event generic implementation includes interface module new norace nx_struct nx_union post provides signal task uses abstract extends"),types:a(c),blockKeywords:a("case do else for if switch while struct"),atoms:a("null true false"),hooks:{"#":u},modeProps:{fold:["brace","include"]}}),g("text/x-objectivec",{name:"clike",keywords:a(s+"inline restrict _Bool _Complex _Imaginary BOOL Class bycopy byref id IMP in inout nil oneway out Protocol SEL self super atomic nonatomic retain copy readwrite readonly"),types:a(c),atoms:a("YES NO NULL NILL ON OFF true false"),hooks:{"@":function(e){return e.eatWhile(/[\w\$]/),"keyword"},"#":u,indent:function(e,t,n){if("statement"==t.type&&/^@\w/.test(n))return t.indented}},modeProps:{fold:"brace"}}),g("text/x-squirrel",{name:"clike",keywords:a("base break clone continue const default delete enum extends function in class foreach local resume return this throw typeof yield constructor instanceof static"),types:a(c),blockKeywords:a("case catch class else for foreach if switch try while"),defKeywords:a("function local class"),typeFirstDefinitions:!0,atoms:a("true false null"),hooks:{"#":u},modeProps:{fold:["brace","include"]}});var y=null;g("text/x-ceylon",{name:"clike",keywords:a("abstracts alias assembly assert assign break case catch class continue dynamic else exists extends finally for function given if import in interface is let module new nonempty object of out outer package return satisfies super switch then this throw try value void while"),types:function(e){var t=e.charAt(0);return t===t.toUpperCase()&&t!==t.toLowerCase()},blockKeywords:a("case catch class dynamic else finally for function if interface module new object switch try while"),defKeywords:a("class dynamic function interface module object package value"),builtin:a("abstract actual aliased annotation by default deprecated doc final formal late license native optional sealed see serializable shared suppressWarnings tagged throws variable"),isPunctuationChar:/[\[\]{}\(\),;\:\.`]/,isOperatorChar:/[+\-*&%=<>!?|^~:\/]/,numberStart:/[\d#$]/,number:/^(?:#[\da-fA-F_]+|\$[01_]+|[\d_]+[kMGTPmunpf]?|[\d_]+\.[\d_]+(?:[eE][-+]?\d+|[kMGTPmunpf]|)|)/i,multiLineStrings:!0,typeFirstDefinitions:!0,atoms:a("true false null larger smaller equal empty finished"),indentSwitch:!1,styleDefs:!1,hooks:{"@":function(e){return e.eatWhile(/[\w\$_]/),"meta"},'"':function(e,t){return t.tokenize=function e(t){return function(n,r){for(var i,o=!1,a=!1;!n.eol();){if(!o&&n.match('"')&&("single"==t||n.match('""'))){a=!0;break}if(!o&&n.match("``")){y=e(t),a=!0;break}i=n.next(),o="single"==t&&!o&&"\\"==i}return a&&(r.tokenize=null),"string"}}(e.match('""')?"triple":"single"),t.tokenize(e,t)},"`":function(e,t){return!(!y||!e.match("`"))&&(t.tokenize=y,y=null,t.tokenize(e,t))},"'":function(e){return e.eatWhile(/[\w\$_\xa1-\uffff]/),"atom"},token:function(e,t,n){if(("variable"==n||"type"==n)&&"."==t.prevToken)return"variable-2"}},modeProps:{fold:["brace","import"],closeBrackets:{triples:'"'}}})}(n(0))},function(e,t,n){!function(e){"use strict";e.defineMode("elm",function(){function e(e,t,n){return t(n),n(e,t)}var t=/[a-z_]/,n=/[A-Z]/,r=/[0-9]/,i=/[0-9A-Fa-f]/,o=/[0-7]/,a=/[a-z_A-Z0-9\']/,l=/[-!#$%&*+.\/<=>?@\\^|~:\u03BB\u2192]/,s=/[(),;[\]`{}]/,c=/[ \t\v\f]/;function u(){return function(d,h){if(d.eatWhile(c))return null;var p=d.next();if(s.test(p)){if("{"==p&&d.eat("-")){var m="comment";return d.eat("#")&&(m="meta"),e(d,h,function e(t,n){return 0==n?u():function(r,i){for(var o=n;!r.eol();){var a=r.next();if("{"==a&&r.eat("-"))++o;else if("-"==a&&r.eat("}")&&0==--o)return i(u()),t}return i(e(t,o)),t}}(m,1))}return null}if("'"==p)return d.eat("\\"),d.next(),d.eat("'")?"string":"error";if('"'==p)return e(d,h,f);if(n.test(p))return d.eatWhile(a),d.eat(".")?"qualifier":"variable-2";if(t.test(p)){var g=1===d.pos;return d.eatWhile(a),g?"type":"variable"}if(r.test(p)){if("0"==p){if(d.eat(/[xX]/))return d.eatWhile(i),"integer";if(d.eat(/[oO]/))return d.eatWhile(o),"number"}d.eatWhile(r);var m="number";return d.eat(".")&&(m="number",d.eatWhile(r)),d.eat(/[eE]/)&&(m="number",d.eat(/[-+]/),d.eatWhile(r)),m}return l.test(p)?"-"==p&&d.eat(/-/)&&(d.eatWhile(/-/),!d.eat(l))?(d.skipToEnd(),"comment"):(d.eatWhile(l),"builtin"):"error"}}function f(e,t){for(;!e.eol();){var n=e.next();if('"'==n)return t(u()),"string";if("\\"==n){if(e.eol()||e.eat(c))return t(d),"string";e.eat("&")||e.next()}}return t(u()),"error"}function d(t,n){return t.eat("\\")?e(t,n,f):(t.next(),n(u()),"error")}var h=function(){for(var e={},t=["case","of","as","if","then","else","let","in","infix","infixl","infixr","type","alias","input","output","foreign","loopback","module","where","import","exposing","_","..","|",":","=","\\",'"',"->","<-"],n=t.length;n--;)e[t[n]]="keyword";return e}();return{startState:function(){return{f:u()}},copyState:function(e){return{f:e.f}},token:function(e,t){var n=t.f(e,function(e){t.f=e}),r=e.current();return h.hasOwnProperty(r)?h[r]:n}}}),e.defineMIME("text/x-elm","elm")}(n(0))},function(e,t,n){!function(e){"use strict";e.defineMode("coffeescript",function(e,t){var n="error";function r(e){return new RegExp("^(("+e.join(")|(")+"))\\b")}var i=/^(?:->|=>|\+[+=]?|-[\-=]?|\*[\*=]?|\/[\/=]?|[=!]=|<[><]?=?|>>?=?|%=?|&=?|\|=?|\^=?|\~|!|\?|(or|and|\|\||&&|\?)=)/,o=/^(?:[()\[\]{},:`=;]|\.\.?\.?)/,a=/^[_A-Za-z$][_A-Za-z$0-9]*/,l=/^@[_A-Za-z$][_A-Za-z$0-9]*/,s=r(["and","or","not","is","isnt","in","instanceof","typeof"]),c=["for","while","loop","if","unless","else","switch","try","catch","finally","class"],u=r(c.concat(["break","by","continue","debugger","delete","do","in","of","new","return","then","this","@","throw","when","until","extends"]));c=r(c);var f=/^('{3}|\"{3}|['\"])/,d=/^(\/{3}|\/)/,h=r(["Infinity","NaN","undefined","null","true","false","on","off","yes","no"]);function p(e,t){if(e.sol()){null===t.scope.align&&(t.scope.align=!1);var r=t.scope.offset;if(e.eatSpace()){var c=e.indentation();return c>r&&"coffee"==t.scope.type?"indent":c0&&y(e,t)}if(e.eatSpace())return null;var p=e.peek();if(e.match("####"))return e.skipToEnd(),"comment";if(e.match("###"))return t.tokenize=g,t.tokenize(e,t);if("#"===p)return e.skipToEnd(),"comment";if(e.match(/^-?[0-9\.]/,!1)){var v=!1;if(e.match(/^-?\d*\.\d+(e[\+\-]?\d+)?/i)&&(v=!0),e.match(/^-?\d+\.\d*/)&&(v=!0),e.match(/^-?\.\d+/)&&(v=!0),v)return"."==e.peek()&&e.backUp(1),"number";var b=!1;if(e.match(/^-?0x[0-9a-f]+/i)&&(b=!0),e.match(/^-?[1-9]\d*(e[\+\-]?\d+)?/)&&(b=!0),e.match(/^-?0(?![\dx])/i)&&(b=!0),b)return"number"}if(e.match(f))return t.tokenize=m(e.current(),!1,"string"),t.tokenize(e,t);if(e.match(d)){if("/"!=e.current()||e.match(/^.*\//,!1))return t.tokenize=m(e.current(),!0,"string-2"),t.tokenize(e,t);e.backUp(1)}return e.match(i)||e.match(s)?"operator":e.match(o)?"punctuation":e.match(h)?"atom":e.match(l)||t.prop&&e.match(a)?"property":e.match(u)?"keyword":e.match(a)?"variable":(e.next(),n)}function m(e,r,i){return function(o,a){for(;!o.eol();)if(o.eatWhile(/[^'"\/\\]/),o.eat("\\")){if(o.next(),r&&o.eol())return i}else{if(o.match(e))return a.tokenize=p,i;o.eat(/['"\/]/)}return r&&(t.singleLineStringErrors?i=n:a.tokenize=p),i}}function g(e,t){for(;!e.eol();){if(e.eatWhile(/[^#]/),e.match("###")){t.tokenize=p;break}e.eatWhile("#")}return"comment"}function v(t,n,r){r=r||"coffee";for(var i=0,o=!1,a=null,l=n.scope;l;l=l.prev)if("coffee"===l.type||"}"==l.type){i=l.offset+e.indentUnit;break}"coffee"!==r?(o=null,a=t.column()+t.current().length):n.scope.align&&(n.scope.align=!1),n.scope={offset:i,type:r,prev:n.scope,align:o,alignOffset:a}}function y(e,t){if(t.scope.prev){if("coffee"===t.scope.type){for(var n=e.indentation(),r=!1,i=t.scope;i;i=i.prev)if(n===i.offset){r=!0;break}if(!r)return!0;for(;t.scope.prev&&t.scope.offset!==n;)t.scope=t.scope.prev;return!1}return t.scope=t.scope.prev,!1}}var b={startState:function(e){return{tokenize:p,scope:{offset:e||0,type:"coffee",prev:null,align:!1},prop:!1,dedent:0}},token:function(e,t){var r=null===t.scope.align&&t.scope;r&&e.sol()&&(r.align=!1);var i=function(e,t){var r=t.tokenize(e,t),i=e.current();"return"===i&&(t.dedent=!0),(("->"===i||"=>"===i)&&e.eol()||"indent"===r)&&v(e,t);var o="[({".indexOf(i);if(-1!==o&&v(e,t,"])}".slice(o,o+1)),c.exec(i)&&v(e,t),"then"==i&&y(e,t),"dedent"===r&&y(e,t))return n;if(-1!==(o="])}".indexOf(i))){for(;"coffee"==t.scope.type&&t.scope.prev;)t.scope=t.scope.prev;t.scope.type==i&&(t.scope=t.scope.prev)}return t.dedent&&e.eol()&&("coffee"==t.scope.type&&t.scope.prev&&(t.scope=t.scope.prev),t.dedent=!1),r}(e,t);return i&&"comment"!=i&&(r&&(r.align=!0),t.prop="punctuation"==i&&"."==e.current()),i},indent:function(e,t){if(e.tokenize!=p)return 0;var n=e.scope,r=t&&"])}".indexOf(t.charAt(0))>-1;if(r)for(;"coffee"==n.type&&n.prev;)n=n.prev;var i=r&&n.type===t.charAt(0);return n.align?n.alignOffset-(i?1:0):(i?n.prev:n).offset},lineComment:"#",fold:"indent"};return b}),e.defineMIME("application/vnd.coffeescript","coffeescript"),e.defineMIME("text/x-coffeescript","coffeescript"),e.defineMIME("text/coffeescript","coffeescript")}(n(0))},function(e,t,n){!function(e){"use strict";function t(e,t,n,r){this.state=e,this.mode=t,this.depth=n,this.prev=r}e.defineMode("jsx",function(n,r){var i=e.getMode(n,{name:"xml",allowMissing:!0,multilineTagIndentPastTag:!1,allowMissingTagName:!0}),o=e.getMode(n,r&&r.base||"javascript");function a(e){var t=e.tagName;e.tagName=null;var n=i.indent(e,"");return e.tagName=t,n}function l(r,s){return s.context.mode==i?function(r,s,c){if(2==c.depth)return r.match(/^.*?\*\//)?c.depth=1:r.skipToEnd(),"comment";if("{"==r.peek()){i.skipAttribute(c.state);var u=a(c.state),f=c.state.context;if(f&&r.match(/^[^>]*>\s*$/,!1)){for(;f.prev&&!f.startOfLine;)f=f.prev;f.startOfLine?u-=n.indentUnit:c.prev.state.lexical&&(u=c.prev.state.lexical.indented)}else 1==c.depth&&(u+=n.indentUnit);return s.context=new t(e.startState(o,u),o,0,s.context),null}if(1==c.depth){if("<"==r.peek())return i.skipAttribute(c.state),s.context=new t(e.startState(i,a(c.state)),i,0,s.context),null;if(r.match("//"))return r.skipToEnd(),"comment";if(r.match("/*"))return c.depth=2,l(r,s)}var d,h=i.token(r,c.state),p=r.current();return/\btag\b/.test(h)?/>$/.test(p)?c.state.context?c.depth=0:s.context=s.context.prev:/^-1&&r.backUp(p.length-d),h}(r,s,s.context):function(n,r,a){if("<"==n.peek()&&o.expressionAllowed(n,a.state))return o.skipExpression(a.state),r.context=new t(e.startState(i,o.indent(a.state,"")),i,0,r.context),null;var l=o.token(n,a.state);if(!l&&null!=a.depth){var s=n.current();"{"==s?a.depth++:"}"==s&&0==--a.depth&&(r.context=r.context.prev)}return l}(r,s,s.context)}return{startState:function(){return{context:new t(e.startState(o),o)}},copyState:function(n){return{context:function n(r){return new t(e.copyState(r.mode,r.state),r.mode,r.depth,r.prev&&n(r.prev))}(n.context)}},token:l,indent:function(e,t,n){return e.context.mode.indent(e.context.state,t,n)},innerMode:function(e){return e.context}}},"xml","javascript"),e.defineMIME("text/jsx","jsx"),e.defineMIME("text/typescript-jsx",{name:"jsx",base:{name:"javascript",typescript:!0}})}(n(0),n(2),n(3))},function(e,t,n){!function(e){"use strict";var t={script:[["lang",/(javascript|babel)/i,"javascript"],["type",/^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^module$|^$/i,"javascript"],["type",/./,"text/plain"],[null,null,"javascript"]],style:[["lang",/^css$/i,"css"],["type",/^(text\/)?(x-)?(stylesheet|css)$/i,"css"],["type",/./,"text/plain"],[null,null,"css"]]},n={};function r(e,t){var r=e.match(function(e){var t=n[e];return t||(n[e]=new RegExp("\\s+"+e+"\\s*=\\s*('|\")?([^'\"]+)('|\")?\\s*"))}(t));return r?/^\s*(.*?)\s*$/.exec(r[2])[1]:""}function i(e,t){return new RegExp((t?"^":"")+"","i")}function o(e,t){for(var n in e)for(var r=t[n]||(t[n]=[]),i=e[n],o=i.length-1;o>=0;o--)r.unshift(i[o])}e.defineMode("htmlmixed",function(n,a){var l=e.getMode(n,{name:"xml",htmlMode:!0,multilineTagIndentFactor:a.multilineTagIndentFactor,multilineTagIndentPastTag:a.multilineTagIndentPastTag}),s={},c=a&&a.tags,u=a&&a.scriptTypes;if(o(t,s),c&&o(c,s),u)for(var f=u.length-1;f>=0;f--)s.script.unshift(["type",u[f].matches,u[f].mode]);function d(t,o){var a,c=l.token(t,o.htmlState),u=/\btag\b/.test(c);if(u&&!/[<>\s\/]/.test(t.current())&&(a=o.htmlState.tagName&&o.htmlState.tagName.toLowerCase())&&s.hasOwnProperty(a))o.inTag=a+" ";else if(o.inTag&&u&&/>$/.test(t.current())){var f=/^([\S]+) (.*)/.exec(o.inTag);o.inTag=null;var h=">"==t.current()&&function(e,t){for(var n=0;n-1?e.backUp(r.length-i):r.match(/<\/?$/)&&(e.backUp(r.length),e.match(t,!1)||e.match(r)),n}(e,g,t.localMode.token(e,t.localState))},o.localMode=p,o.localState=e.startState(p,l.indent(o.htmlState,""))}else o.inTag&&(o.inTag+=t.current(),t.eol()&&(o.inTag+=" "));return c}return{startState:function(){var t=e.startState(l);return{token:d,inTag:null,localMode:null,localState:null,htmlState:t}},copyState:function(t){var n;return t.localState&&(n=e.copyState(t.localMode,t.localState)),{token:t.token,inTag:t.inTag,localMode:t.localMode,localState:n,htmlState:e.copyState(l,t.htmlState)}},token:function(e,t){return t.token(e,t)},indent:function(t,n,r){return!t.localMode||/^\s*<\//.test(n)?l.indent(t.htmlState,n):t.localMode.indent?t.localMode.indent(t.localState,n,r):e.Pass},innerMode:function(e){return{state:e.localState||e.htmlState,mode:e.localMode||l}}}},"xml","javascript","css"),e.defineMIME("text/html","htmlmixed")}(n(0),n(2),n(3),n(7))},function(e,t,n){!function(e){"use strict";e.defineMode("haxe",function(e,t){var n=e.indentUnit;function r(e){return{type:e,style:"keyword"}}var i,o=r("keyword a"),a=r("keyword b"),l=r("keyword c"),s=r("operator"),c={type:"atom",style:"atom"},u={type:"attribute",style:"attribute"},f=r("typedef"),d={if:o,while:o,else:a,do:a,try:a,return:l,break:l,continue:l,new:l,throw:l,var:r("var"),inline:u,static:u,using:r("import"),public:u,private:u,cast:r("cast"),import:r("import"),macro:r("macro"),function:r("function"),catch:r("catch"),untyped:r("untyped"),callback:r("cb"),for:r("for"),switch:r("switch"),case:r("case"),default:r("default"),in:s,never:r("property_access"),trace:r("trace"),class:f,abstract:f,enum:f,interface:f,typedef:f,extends:f,implements:f,dynamic:f,true:c,false:c,null:c},h=/[+\-*&%=<>!?|]/;function p(e,t,n){return t.tokenize=n,n(e,t)}function m(e,t){for(var n,r=!1;null!=(n=e.next());){if(n==t&&!r)return!0;r=!r&&"\\"==n}}function g(e,t,n){return f=e,i=n,t}function v(e,t){var n=e.next();if('"'==n||"'"==n)return p(e,t,(r=n,function(e,t){return m(e,r)&&(t.tokenize=v),g("string","string")}));if(/[\[\]{}\(\),;\:\.]/.test(n))return g(n);if("0"==n&&e.eat(/x/i))return e.eatWhile(/[\da-f]/i),g("number","number");if(/\d/.test(n)||"-"==n&&e.eat(/\d/))return e.match(/^\d*(?:\.\d*(?!\.))?(?:[eE][+\-]?\d+)?/),g("number","number");if(t.reAllowed&&"~"==n&&e.eat(/\//))return m(e,"/"),e.eatWhile(/[gimsu]/),g("regexp","string-2");if("/"==n)return e.eat("*")?p(e,t,y):e.eat("/")?(e.skipToEnd(),g("comment","comment")):(e.eatWhile(h),g("operator",null,e.current()));if("#"==n)return e.skipToEnd(),g("conditional","meta");if("@"==n)return e.eat(/:/),e.eatWhile(/[\w_]/),g("metadata","meta");if(h.test(n))return e.eatWhile(h),g("operator",null,e.current());if(/[A-Z]/.test(n))return e.eatWhile(/[\w_<>]/),g("type","variable-3",i=e.current());e.eatWhile(/[\w_]/);var r,i=e.current(),o=d.propertyIsEnumerable(i)&&d[i];return o&&t.kwAllowed?g(o.type,o.style,i):g("variable","variable",i)}function y(e,t){for(var n,r=!1;n=e.next();){if("/"==n&&r){t.tokenize=v;break}r="*"==n}return g("comment","comment")}var b={atom:!0,number:!0,variable:!0,string:!0,regexp:!0};function x(e,t,n,r,i,o){this.indented=e,this.column=t,this.type=n,this.prev=i,this.info=o,null!=r&&(this.align=r)}function w(e,t){for(var n=e.localVars;n;n=n.next)if(n.name==t)return!0}function k(e,t){if(/[a-z]/.test(t.charAt(0)))return!1;for(var n=e.importedtypes.length,r=0;r=0;e--)S.cc.push(arguments[e])}function M(){return L.apply(null,arguments),!0}function T(e,t){for(var n=t;n;n=n.next)if(n.name==e)return!0;return!1}function A(e){var t=S.state;if(t.context){if(S.marked="def",T(e,t.localVars))return;t.localVars={name:e,next:t.localVars}}else if(t.globalVars){if(T(e,t.globalVars))return;t.globalVars={name:e,next:t.globalVars}}}var O={name:"this",next:null};function E(){S.state.context||(S.state.localVars=O),S.state.context={prev:S.state.context,vars:S.state.localVars}}function N(){S.state.localVars=S.state.context.vars,S.state.context=S.state.context.prev}function P(e,t){var n=function(){var n=S.state;n.lexical=new x(n.indented,S.stream.column(),e,null,n.lexical,t)};return n.lex=!0,n}function I(){var e=S.state;e.lexical.prev&&(")"==e.lexical.type&&(e.indented=e.lexical.indented),e.lexical=e.lexical.prev)}function R(e){return function t(n){return n==e?M():";"==e?L():M(t)}}function B(e){return"@"==e?M(_):"var"==e?M(P("vardef"),X,R(";"),I):"keyword a"==e?M(P("form"),D,B,I):"keyword b"==e?M(P("form"),B,I):"{"==e?M(P("}"),E,G,I,N):";"==e?M():"attribute"==e?M(z):"function"==e?M(Q):"for"==e?M(P("form"),R("("),P(")"),Z,R(")"),I,B,I):"variable"==e?M(P("stat"),U):"switch"==e?M(P("form"),D,P("}","switch"),R("{"),G,I,I):"case"==e?M(D,R(":")):"default"==e?M(R(":")):"catch"==e?M(P("form"),E,R("("),re,R(")"),B,I,N):"import"==e?M(K,R(";")):"typedef"==e?M(j):L(P("stat"),D,R(";"),I)}function D(e){return b.hasOwnProperty(e)?M(W):"type"==e?M(W):"function"==e?M(Q):"keyword c"==e?M(F):"("==e?M(P(")"),F,R(")"),I,W):"operator"==e?M(D):"["==e?M(P("]"),$(F,"]"),I,W):"{"==e?M(P("}"),$(q,"}"),I,W):M()}function F(e){return e.match(/[;\}\)\],]/)?L():L(D)}function W(e,t){return"operator"==e&&/\+\+|--/.test(t)?M(W):"operator"==e||":"==e?M(D):";"!=e?"("==e?M(P(")"),$(D,")"),I,W):"."==e?M(V,W):"["==e?M(P("]"),D,R("]"),I,W):void 0:void 0}function z(e){return"attribute"==e?M(z):"function"==e?M(Q):"var"==e?M(X):void 0}function _(e){return":"==e?M(_):"variable"==e?M(_):"("==e?M(P(")"),$(H,")"),I,B):void 0}function H(e){if("variable"==e)return M()}function K(e,t){return"variable"==e&&/[A-Z]/.test(t.charAt(0))?(C(t),M()):"variable"==e||"property"==e||"."==e||"*"==t?M(K):void 0}function j(e,t){return"variable"==e&&/[A-Z]/.test(t.charAt(0))?(C(t),M()):"type"==e&&/[A-Z]/.test(t.charAt(0))?M():void 0}function U(e){return":"==e?M(I,B):L(W,R(";"),I)}function V(e){if("variable"==e)return S.marked="property",M()}function q(e){if("variable"==e&&(S.marked="property"),b.hasOwnProperty(e))return M(R(":"),D)}function $(e,t){function n(r){return","==r?M(e,n):r==t?M():M(R(t))}return function(r){return r==t?M():L(e,n)}}function G(e){return"}"==e?M():L(B,G)}function X(e,t){return"variable"==e?(A(t),M(ee,Y)):M()}function Y(e,t){return"="==t?M(D,Y):","==e?M(X):void 0}function Z(e,t){return"variable"==e?(A(t),M(J,D)):L()}function J(e,t){if("in"==t)return M()}function Q(e,t){return"variable"==e||"type"==e?(A(t),M(Q)):"new"==t?M(Q):"("==e?M(P(")"),E,$(re,")"),I,ee,B,N):void 0}function ee(e){if(":"==e)return M(te)}function te(e){return"type"==e?M():"variable"==e?M():"{"==e?M(P("}"),$(ne,"}"),I):void 0}function ne(e){if("variable"==e)return M(ee)}function re(e,t){if("variable"==e)return A(t),M(ee)}return N.lex=!0,I.lex=!0,{startState:function(e){var r={tokenize:v,reAllowed:!0,kwAllowed:!0,cc:[],lexical:new x((e||0)-n,0,"block",!1),localVars:t.localVars,importedtypes:["Int","Float","String","Void","Std","Bool","Dynamic","Array"],context:t.localVars&&{vars:t.localVars},indented:0};return t.globalVars&&"object"==typeof t.globalVars&&(r.globalVars=t.globalVars),r},token:function(e,t){if(e.sol()&&(t.lexical.hasOwnProperty("align")||(t.lexical.align=!1),t.indented=e.indentation()),e.eatSpace())return null;var n=t.tokenize(e,t);return"comment"==f?n:(t.reAllowed=!("operator"!=f&&"keyword c"!=f&&!f.match(/^[\[{}\(,;:]$/)),t.kwAllowed="."!=f,function(e,t,n,r,i){var o=e.cc;for(S.state=e,S.stream=i,S.marked=null,S.cc=o,e.lexical.hasOwnProperty("align")||(e.lexical.align=!0);;){var a=o.length?o.pop():B;if(a(n,r)){for(;o.length&&o[o.length-1].lex;)o.pop()();return S.marked?S.marked:"variable"==n&&w(e,r)?"variable-2":"variable"==n&&k(e,r)?"variable-3":t}}}(t,n,f,i,e))},indent:function(e,t){if(e.tokenize!=v)return 0;var r=t&&t.charAt(0),i=e.lexical;"stat"==i.type&&"}"==r&&(i=i.prev);var o=i.type,a=r==o;return"vardef"==o?i.indented+4:"form"==o&&"{"==r?i.indented:"stat"==o||"form"==o?i.indented+n:"switch"!=i.info||a?i.align?i.column+(a?0:1):i.indented+(a?0:n):i.indented+(/^(?:case|default)\b/.test(t)?n:2*n)},electricChars:"{}",blockCommentStart:"/*",blockCommentEnd:"*/",lineComment:"//"}}),e.defineMIME("text/x-haxe","haxe"),e.defineMode("hxml",function(){return{startState:function(){return{define:!1,inString:!1}},token:function(e,t){var n=e.peek(),r=e.sol();if("#"==n)return e.skipToEnd(),"comment";if(r&&"-"==n){var i="variable-2";return e.eat(/-/),"-"==e.peek()&&(e.eat(/-/),i="keyword a"),"D"==e.peek()&&(e.eat(/[D]/),i="keyword c",t.define=!0),e.eatWhile(/[A-Z]/i),i}var n=e.peek();return 0==t.inString&&"'"==n&&(t.inString=!0,e.next()),1==t.inString?(e.skipTo("'")||e.skipToEnd(),"'"==e.peek()&&(e.next(),t.inString=!1),"string"):(e.next(),null)},lineComment:"#"}}),e.defineMIME("text/x-hxml","hxml")}(n(0))},function(e,t,n){!function(e){"use strict";var t={},n=/[^\s\u00a0]/,r=e.Pos;function i(e){var t=e.search(n);return-1==t?0:t}function o(e,t){var n=e.getMode();return!1!==n.useInnerComments&&n.innerMode?e.getModeAt(t):n}e.commands.toggleComment=function(e){e.toggleComment()},e.defineExtension("toggleComment",function(e){e||(e=t);for(var n=1/0,i=this.listSelections(),o=null,a=i.length-1;a>=0;a--){var l=i[a].from(),s=i[a].to();l.line>=n||(s.line>=n&&(s=r(n,0)),n=l.line,null==o?this.uncomment(l,s,e)?o="un":(this.lineComment(l,s,e),o="line"):"un"==o?this.uncomment(l,s,e):this.lineComment(l,s,e))}}),e.defineExtension("lineComment",function(e,a,l){l||(l=t);var s=this,c=o(s,e),u=s.getLine(e.line);if(null!=u&&(f=e,d=u,!/\bstring\b/.test(s.getTokenTypeAt(r(f.line,0)))||/^[\'\"\`]/.test(d))){var f,d,h=l.lineComment||c.lineComment;if(h){var p=Math.min(0!=a.ch||a.line==e.line?a.line+1:a.line,s.lastLine()+1),m=null==l.padding?" ":l.padding,g=l.commentBlankLines||e.line==a.line;s.operation(function(){if(l.indent){for(var t=null,o=e.line;oc.length)&&(t=c)}for(var o=e.line;of||l.operation(function(){if(0!=a.fullLines){var t=n.test(l.getLine(f));l.replaceRange(d+u,r(f)),l.replaceRange(c+d,r(e.line,0));var o=a.blockCommentLead||s.blockCommentLead;if(null!=o)for(var h=e.line+1;h<=f;++h)(h!=f||t)&&l.replaceRange(o+d,r(h,0))}else l.replaceRange(u,i),l.replaceRange(c,e)})}}else(a.lineComment||s.lineComment)&&0!=a.fullLines&&l.lineComment(e,i,a)}),e.defineExtension("uncomment",function(e,i,a){a||(a=t);var l,s=this,c=o(s,e),u=Math.min(0!=i.ch||i.line==e.line?i.line:i.line-1,s.lastLine()),f=Math.min(e.line,u),d=a.lineComment||c.lineComment,h=[],p=null==a.padding?" ":a.padding;e:if(d){for(var m=f;m<=u;++m){var g=s.getLine(m),v=g.indexOf(d);if(v>-1&&!/comment/.test(s.getTokenTypeAt(r(m,v+1)))&&(v=-1),-1==v&&n.test(g))break e;if(v>-1&&n.test(g.slice(0,v)))break e;h.push(g)}if(s.operation(function(){for(var e=f;e<=u;++e){var t=h[e-f],n=t.indexOf(d),i=n+d.length;n<0||(t.slice(i,i+p.length)==p&&(i+=p.length),l=!0,s.replaceRange("",r(e,n),r(e,i)))}}),l)return!0}var y=a.blockCommentStart||c.blockCommentStart,b=a.blockCommentEnd||c.blockCommentEnd;if(!y||!b)return!1;var x=a.blockCommentLead||c.blockCommentLead,w=s.getLine(f),k=w.indexOf(y);if(-1==k)return!1;var C=u==f?w:s.getLine(u),S=C.indexOf(b,u==f?k+y.length:0),L=r(f,k+1),M=r(u,S+1);if(-1==S||!/comment/.test(s.getTokenTypeAt(L))||!/comment/.test(s.getTokenTypeAt(M))||s.getRange(L,M,"\n").indexOf(b)>-1)return!1;var T=w.lastIndexOf(y,e.ch),A=-1==T?-1:w.slice(0,e.ch).indexOf(b,T+y.length);if(-1!=T&&-1!=A&&A+b.length!=e.ch)return!1;A=C.indexOf(b,i.ch);var O=C.slice(i.ch).lastIndexOf(y,A-i.ch);return T=-1==A||-1==O?-1:i.ch+O,(-1==A||-1==T||T==i.ch)&&(s.operation(function(){s.replaceRange("",r(u,S-(p&&C.slice(S-p.length,S)==p?p.length:0)),r(u,S+b.length));var e=k+y.length;if(p&&w.slice(e,e+p.length)==p&&(e+=p.length),s.replaceRange("",r(f,k),r(f,e)),x)for(var t=f+1;t<=u;++t){var i=s.getLine(t),o=i.indexOf(x);if(-1!=o&&!n.test(i.slice(0,o))){var a=o+x.length;p&&i.slice(a,a+p.length)==p&&(a+=p.length),s.replaceRange("",r(t,o),r(t,a))}}}),!0)})}(n(0))},function(e,t,n){!function(e){var t={pairs:"()[]{}''\"\"",triples:"",explode:"[]{}"},n=e.Pos;function r(e,n){return"pairs"==n&&"string"==typeof e?e:"object"==typeof e&&null!=e[n]?e[n]:t[n]}e.defineOption("autoCloseBrackets",!1,function(t,n,a){a&&a!=e.Init&&(t.removeKeyMap(i),t.state.closeBrackets=null),n&&(o(r(n,"pairs")),t.state.closeBrackets=n,t.addKeyMap(i))});var i={Backspace:function(t){var i=l(t);if(!i||t.getOption("disableInput"))return e.Pass;for(var o=r(i,"pairs"),a=t.listSelections(),s=0;s=0;s--){var f=a[s].head;t.replaceRange("",n(f.line,f.ch-1),n(f.line,f.ch+1),"+delete")}},Enter:function(t){var n=l(t),i=n&&r(n,"explode");if(!i||t.getOption("disableInput"))return e.Pass;for(var o=t.listSelections(),a=0;a1&&d.indexOf(i)>=0&&t.getRange(n(b.line,b.ch-2),b)==i+i){if(b.ch>2&&/\bstring/.test(t.getTokenTypeAt(n(b.line,b.ch-2))))return e.Pass;v="addFour"}else if(h){var w=0==b.ch?" ":t.getRange(n(b.line,b.ch-1),b);if(e.isWordChar(x)||w==i||e.isWordChar(w))return e.Pass;v="both"}else{if(!m||t.getLine(b.line).length!=b.ch&&!s(x,a)&&!/\s/.test(x))return e.Pass;v="both"}else v=h&&u(t,b)?"both":d.indexOf(i)>=0&&t.getRange(b,n(b.line,b.ch+3))==i+i+i?"skipThree":"skip";if(f){if(f!=v)return e.Pass}else f=v}var k=c%2?a.charAt(c-1):i,C=c%2?i:a.charAt(c+1);t.operation(function(){if("skip"==f)t.execCommand("goCharRight");else if("skipThree"==f)for(var r=0;r<3;r++)t.execCommand("goCharRight");else if("surround"==f){for(var i=t.getSelections(),r=0;r0,{anchor:new n(o.anchor.line,o.anchor.ch+(a?-1:1)),head:new n(o.head.line,o.head.ch+(a?1:-1))});t.setSelections(i)}else"both"==f?(t.replaceSelection(k+C,null),t.triggerElectric(k+C),t.execCommand("goCharLeft")):"addFour"==f&&(t.replaceSelection(k+k+k+k,"before"),t.execCommand("goCharRight"));var o,a})}(i,t)}}function l(e){var t=e.state.closeBrackets;if(!t||t.override)return t;var n=e.getModeAt(e.getCursor());return n.closeBrackets||t}function s(e,t){var n=t.lastIndexOf(e);return n>-1&&n%2==1}function c(e,t){var r=e.getRange(n(t.line,t.ch-1),n(t.line,t.ch+1));return 2==r.length?r:null}function u(e,t){var r=e.getTokenAt(n(t.line,t.ch+1));return/\bstring/.test(r.type)&&r.start==t.ch&&(0==t.ch||!/\bstring/.test(e.getTokenTypeAt(t)))}o(t.pairs+"`")}(n(0))},function(e,t,n){!function(e){"use strict";function t(e){return e.state.search||(e.state.search=new function(){this.posFrom=this.posTo=this.lastQuery=this.query=null,this.overlay=null})}function n(e){return"string"==typeof e&&e==e.toLowerCase()}function r(e,t,r){return e.getSearchCursor(t,r,{caseFold:n(t),multiline:!0})}function i(e,t,n,r,i){e.openDialog?e.openDialog(t,i,{value:r,selectValueOnOpen:!0}):i(prompt(n,r))}function o(e){return e.replace(/\\(.)/g,function(e,t){return"n"==t?"\n":"r"==t?"\r":t})}function a(e){var t=e.match(/^\/(.*)\/([a-z]*)$/);if(t)try{e=new RegExp(t[1],-1==t[2].indexOf("i")?"":"i")}catch(e){}else e=o(e);return("string"==typeof e?""==e:e.test(""))&&(e=/x^/),e}var l;function s(e,t,r){t.queryText=r,t.query=a(r),e.removeOverlay(t.overlay,n(t.query)),t.overlay=function(e,t){return"string"==typeof e?e=new RegExp(e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&"),t?"gi":"g"):e.global||(e=new RegExp(e.source,e.ignoreCase?"gi":"g")),{token:function(t){e.lastIndex=t.pos;var n=e.exec(t.string);if(n&&n.index==t.pos)return t.pos+=n[0].length||1,"searching";n?t.pos=n.index:t.skipToEnd()}}}(t.query,n(t.query)),e.addOverlay(t.overlay),e.showMatchesOnScrollbar&&(t.annotate&&(t.annotate.clear(),t.annotate=null),t.annotate=e.showMatchesOnScrollbar(t.query,n(t.query)))}function c(n,r,o,a){if(!l){let e=n.getWrapperElement().ownerDocument,t=e.createElement("input");t.type="search",t.placeholder=n.l10n("findCmd.promptMessage"),t.style.marginInlineStart="1em",t.style.marginInlineEnd="1em",t.style.flexGrow="1",t.addEventListener("focus",()=>t.select()),(l=e.createElement("div")).appendChild(t),l.style.display="flex"}var c=t(n);if(c.query)return u(n,r);var d=n.getSelection()||c.lastQuery;if(d instanceof RegExp&&"x^"==d.source&&(d=null),o&&n.openDialog){var h=null,p=function(t,r){e.e_stop(r),t&&(t!=c.queryText&&(s(n,c,t),c.posFrom=c.posTo=n.getCursor()),h&&(h.style.opacity=1),u(n,r.shiftKey,function(e,t){var r;t.line<3&&document.querySelector&&(r=n.display.wrapper.querySelector(".CodeMirror-dialog"))&&r.getBoundingClientRect().bottom-4>n.cursorCoords(t,"window").top&&((h=r).style.opacity=.4)}))};!function(e,t,n,r,i){e.openDialog(t,r,{value:n,selectValueOnOpen:!0,closeOnEnter:!1,onClose:function(){f(e)},onKeyDown:i})}(n,l,d,p,function(r,i){var o=e.keyName(r),a=n.getOption("extraKeys"),l=a&&a[o]||e.keyMap[n.getOption("keyMap")][o];"findNext"==l||"findPrev"==l||"findPersistentNext"==l||"findPersistentPrev"==l?(e.e_stop(r),s(n,t(n),i),n.execCommand(l)):"find"!=l&&"findPersistent"!=l||(e.e_stop(r),p(i,r))}),a&&d&&(s(n,c,d),u(n,r))}else i(n,l,"Search for:",d,function(e){e&&!c.query&&n.operation(function(){s(n,c,e),c.posFrom=c.posTo=n.getCursor(),u(n,r)})})}function u(n,i,o){n.operation(function(){var a=t(n),l=r(n,a.query,i?a.posFrom:a.posTo);(l.find(i)||(l=r(n,a.query,i?e.Pos(n.lastLine()):e.Pos(n.firstLine(),0))).find(i))&&(n.setSelection(l.from(),l.to()),n.scrollIntoView({from:l.from(),to:l.to()},20),a.posFrom=l.from(),a.posTo=l.to(),o&&o(l.from(),l.to()))})}function f(e){e.operation(function(){var n=t(e);n.lastQuery=n.query,n.query&&(n.query=n.queryText=null,e.removeOverlay(n.overlay),n.annotate&&(n.annotate.clear(),n.annotate=null))})}function d(e,t,n){e.operation(function(){for(var i=r(e,t);i.findNext();)if("string"!=typeof t){var o=e.getRange(i.from(),i.to()).match(t);i.replace(n.replace(/\$(\d)/g,function(e,t){return o[t]}))}else i.replace(n)})}function h(e,n){if(e.getOption("readOnly"))return;var l=e.getSelection()||t(e).lastQuery;let s=e.getWrapperElement().ownerDocument,c=s.createElement("span");c.classList.add("CodeMirror-search-label"),c.textContent=n?"Replace all:":"Replace:";let u=s.createDocumentFragment();u.appendChild(c.cloneNode(!0));let h=s.createElement("input");h.setAttribute("type","text"),h.setAttribute("style","width: 10em"),h.classList.add("CodeMirror-search-field"),u.appendChild(h);let p=s.createElement("span");p.setAttribute("style","color: #888"),p.classList.add("CodeMirror-search-hint"),p.textContent="(Use /re/ syntax for regexp search)",u.appendChild(p),i(e,u,c,l,function(t){if(!t)return;t=a(t);let l=s.createDocumentFragment(),u=c.cloneNode(!1);u.textContent="With:",l.appendChild(u);let h=s.createElement("input");h.setAttribute("type","text"),h.setAttribute("style","width: 10em"),h.classList.add("CodeMirror-search-field"),l.appendChild(h),i(e,l,"Replace with:","",function(i){if(i=o(i),n)d(e,t,i);else{f(e);var a=r(e,t,e.getCursor("from")),l=function(){var n,o=a.from();if(!(n=a.findNext())&&(a=r(e,t),!(n=a.findNext())||o&&a.from().line==o.line&&a.from().ch==o.ch))return;e.setSelection(a.from(),a.to()),e.scrollIntoView({from:a.from(),to:a.to()});let f=s.createDocumentFragment(),h=c.cloneNode(!1);h.textContent="Replace?",f.appendChild(h);let p=s.createElement("button");p.textContent="Yes",f.appendChild(p);let m=s.createElement("button");m.textContent="No",f.appendChild(m);let g=s.createElement("button");g.textContent="All",f.appendChild(g);let v=s.createElement("button");v.textContent="Stop",f.appendChild(v),function(e,t,n,r){e.openConfirm?e.openConfirm(t,r):confirm(n)&&r[0]()}(e,f,"Replace?",[function(){u(n)},l,function(){d(e,t,i)}])},u=function(e){a.replace("string"==typeof t?i:i.replace(/\$(\d)/g,function(t,n){return e[n]})),l()};l()}})})}e.commands.find=function(e){f(e),c(e)},e.commands.findPersistent=function(e){f(e),c(e,!1,!0)},e.commands.findPersistentNext=function(e){c(e,!1,!0,!0)},e.commands.findPersistentPrev=function(e){c(e,!0,!0,!0)},e.commands.findNext=c,e.commands.findPrev=function(e){c(e,!0)},e.commands.clearSearch=f,e.commands.replace=h,e.commands.replaceAll=function(e){h(e,!0)}}(n(0),n(1),n(5))},function(e,t,n){n(5),n(1),n(27),n(4),n(26),n(25),n(3),n(2),n(7),n(24),n(23),n(22),n(21),n(20),n(19),n(18),n(17),n(16),n(15),n(14),n(13),n(6),n(12),n(11),n(10),n(9),n(8),e.exports=n(0)}]); \ No newline at end of file +var CodeMirror=function(e){var t={};function n(r){if(t[r])return t[r].exports;var i=t[r]={i:r,l:!1,exports:{}};return e[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)n.d(r,i,function(t){return e[t]}.bind(null,i));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=28)}([function(e,t,n){e.exports=function(){"use strict";var e=navigator.userAgent,t=navigator.platform,n=/gecko\/\d/i.test(e),r=/MSIE \d/.test(e),i=/Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(e),o=/Edge\/(\d+)/.exec(e),a=r||i||o,l=a&&(r?document.documentMode||6:+(o||i)[1]),s=!o&&/WebKit\//.test(e),c=s&&/Qt\/\d+\.\d+/.test(e),u=!o&&/Chrome\//.test(e),f=/Opera\//.test(e),d=/Apple Computer/.test(navigator.vendor),h=/Mac OS X 1\d\D([8-9]|\d\d)\D/.test(e),p=/PhantomJS/.test(e),m=!o&&/AppleWebKit/.test(e)&&/Mobile\/\w+/.test(e),g=/Android/.test(e),v=m||g||/webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(e),y=m||/Mac/.test(t),b=/\bCrOS\b/.test(e),x=/win/i.test(t),w=f&&e.match(/Version\/(\d*\.\d*)/);w&&(w=Number(w[1])),w&&w>=15&&(f=!1,s=!0);var k=y&&(c||f&&(null==w||w<12.11)),C=n||a&&l>=9;function S(e){return new RegExp("(^|\\s)"+e+"(?:$|\\s)\\s*")}var L,M=function(e,t){var n=e.className,r=S(t).exec(n);if(r){var i=n.slice(r.index+r[0].length);e.className=n.slice(0,r.index)+(i?r[1]+i:"")}};function T(e){for(var t=e.childNodes.length;t>0;--t)e.removeChild(e.firstChild);return e}function A(e,t){return T(e).appendChild(t)}function O(e,t,n,r){var i=document.createElement(e);if(n&&(i.className=n),r&&(i.style.cssText=r),"string"==typeof t)i.appendChild(document.createTextNode(t));else if(t)for(var o=0;o=t)return a+(t-o);a+=l-o,a+=n-a%n,o=l+1}}m?B=function(e){e.selectionStart=0,e.selectionEnd=e.value.length}:a&&(B=function(e){try{e.select()}catch(e){}});var W=function(){this.id=null};function _(e,t){for(var n=0;n=t)return r+Math.min(a,t-i);if(i+=o-r,r=o+1,(i+=n-i%n)>=t)return r}}var $=[""];function G(e){for(;$.length<=e;)$.push(X($)+" ");return $[e]}function X(e){return e[e.length-1]}function Y(e,t){for(var n=[],r=0;r"€"&&(e.toUpperCase()!=e.toLowerCase()||Q.test(e))}function te(e,t){return t?!!(t.source.indexOf("\\w")>-1&&ee(e))||t.test(e):ee(e)}function ne(e){for(var t in e)if(e.hasOwnProperty(t)&&e[t])return!1;return!0}var re=/[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/;function ie(e){return e.charCodeAt(0)>=768&&re.test(e)}function oe(e,t,n){for(;(n<0?t>0:tn?-1:1;;){if(t==n)return t;var i=(t+n)/2,o=r<0?Math.ceil(i):Math.floor(i);if(o==t)return e(o)?t:n;e(o)?n=o:t=o+r}}function le(e,t){if((t-=e.first)<0||t>=e.size)throw new Error("There is no line "+(t+e.first)+" in the document.");for(var n=e;!n.lines;)for(var r=0;;++r){var i=n.children[r],o=i.chunkSize();if(t=e.first&&tn?me(n,le(e,n).text.length):function(e,t){var n=e.ch;return null==n||n>t?me(e.line,t):n<0?me(e.line,0):e}(t,le(e,t.line).text.length)}function Ce(e,t){for(var n=[],r=0;r=t:o.to>t);(r||(r=[])).push(new Me(a,o.from,s?null:o.to))}}return r}(n,i,a),s=function(e,t,n){var r;if(e)for(var i=0;i=t:o.to>t);if(l||o.from==t&&"bookmark"==a.type&&(!n||o.marker.insertLeft)){var s=null==o.from||(a.inclusiveLeft?o.from<=t:o.from0&&l)for(var x=0;xt)&&(!n||Be(n,o.marker)<0)&&(n=o.marker)}return n}function _e(e,t,n,r,i){var o=le(e,t),a=Le&&o.markedSpans;if(a)for(var l=0;l=0&&f<=0||u<=0&&f>=0)&&(u<=0&&(s.marker.inclusiveRight&&i.inclusiveLeft?ge(c.to,n)>=0:ge(c.to,n)>0)||u>=0&&(s.marker.inclusiveRight&&i.inclusiveLeft?ge(c.from,r)<=0:ge(c.from,r)<0)))return!0}}}function He(e){for(var t;t=Fe(e);)e=t.find(-1,!0).line;return e}function Ke(e,t){var n=le(e,t),r=He(n);return n==r?t:fe(r)}function je(e,t){if(t>e.lastLine())return t;var n,r=le(e,t);if(!Ue(e,r))return t;for(;n=ze(r);)r=n.find(1,!0).line;return fe(r)+1}function Ue(e,t){var n=Le&&t.markedSpans;if(n)for(var r=void 0,i=0;it.maxLineLength&&(t.maxLineLength=n,t.maxLine=e)})}var Xe=null;function Ye(e,t,n){var r;Xe=null;for(var i=0;it)return i;o.to==t&&(o.from!=o.to&&"before"==n?r=i:Xe=i),o.from==t&&(o.from!=o.to&&"before"!=n?r=i:Xe=i)}return null!=r?r:Xe}var Ze=function(){var e="bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN",t="nnnnnnNNr%%r,rNNmmmmmmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmmmnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmnNmmmmmmrrmmNmmmmrr1111111111";function n(n){return n<=247?e.charAt(n):1424<=n&&n<=1524?"R":1536<=n&&n<=1785?t.charAt(n-1536):1774<=n&&n<=2220?"r":8192<=n&&n<=8203?"w":8204==n?"b":"L"}var r=/[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/,i=/[stwN]/,o=/[LRr]/,a=/[Lb1n]/,l=/[1n]/;function s(e,t,n){this.level=e,this.from=t,this.to=n}return function(e,t){var c="ltr"==t?"L":"R";if(0==e.length||"ltr"==t&&!r.test(e))return!1;for(var u=e.length,f=[],d=0;d-1&&(r[t]=i.slice(0,o).concat(i.slice(o+1)))}}}function rt(e,t){var n=tt(e,t);if(n.length)for(var r=Array.prototype.slice.call(arguments,2),i=0;i0}function lt(e){e.prototype.on=function(e,t){et(this,e,t)},e.prototype.off=function(e,t){nt(this,e,t)}}function st(e){e.preventDefault?e.preventDefault():e.returnValue=!1}function ct(e){e.stopPropagation?e.stopPropagation():e.cancelBubble=!0}function ut(e){return null!=e.defaultPrevented?e.defaultPrevented:0==e.returnValue}function ft(e){st(e),ct(e)}function dt(e){return e.target||e.srcElement}function ht(e){var t=e.which;return null==t&&(1&e.button?t=1:2&e.button?t=3:4&e.button&&(t=2)),y&&e.ctrlKey&&1==t&&(t=3),t}var pt,mt,gt=function(){if(a&&l<9)return!1;var e=O("div");return"draggable"in e||"dragDrop"in e}();function vt(e){if(null==pt){var t=O("span","​");A(e,O("span",[t,document.createTextNode("x")])),0!=e.firstChild.offsetHeight&&(pt=t.offsetWidth<=1&&t.offsetHeight>2&&!(a&&l<8))}var n=pt?O("span","​"):O("span"," ",null,"display: inline-block; width: 1px; margin-right: -1px");return n.setAttribute("cm-text",""),n}function yt(e){if(null!=mt)return mt;var t=A(e,document.createTextNode("AخA")),n=L(t,0,1).getBoundingClientRect(),r=L(t,1,2).getBoundingClientRect();return T(e),!(!n||n.left==n.right)&&(mt=r.right-n.right<3)}var bt=3!="\n\nb".split(/\n/).length?function(e){for(var t=0,n=[],r=e.length;t<=r;){var i=e.indexOf("\n",t);-1==i&&(i=e.length);var o=e.slice(t,"\r"==e.charAt(i-1)?i-1:i),a=o.indexOf("\r");-1!=a?(n.push(o.slice(0,a)),t+=a+1):(n.push(o),t=i+1)}return n}:function(e){return e.split(/\r\n?|\n/)},xt=window.getSelection?function(e){try{return e.selectionStart!=e.selectionEnd}catch(e){return!1}}:function(e){var t;try{t=e.ownerDocument.selection.createRange()}catch(e){}return!(!t||t.parentElement()!=e)&&0!=t.compareEndPoints("StartToEnd",t)},wt=function(){var e=O("div");return"oncopy"in e||(e.setAttribute("oncopy","return;"),"function"==typeof e.oncopy)}(),kt=null,Ct={},St={};function Lt(e){if("string"==typeof e&&St.hasOwnProperty(e))e=St[e];else if(e&&"string"==typeof e.name&&St.hasOwnProperty(e.name)){var t=St[e.name];"string"==typeof t&&(t={name:t}),(e=J(t,e)).name=t.name}else{if("string"==typeof e&&/^[\w\-]+\/[\w\-]+\+xml$/.test(e))return Lt("application/xml");if("string"==typeof e&&/^[\w\-]+\/[\w\-]+\+json$/.test(e))return Lt("application/json")}return"string"==typeof e?{name:e}:e||{name:"null"}}function Mt(e,t){t=Lt(t);var n=Ct[t.name];if(!n)return Mt(e,"text/plain");var r=n(e,t);if(Tt.hasOwnProperty(t.name)){var i=Tt[t.name];for(var o in i)i.hasOwnProperty(o)&&(r.hasOwnProperty(o)&&(r["_"+o]=r[o]),r[o]=i[o])}if(r.name=t.name,t.helperType&&(r.helperType=t.helperType),t.modeProps)for(var a in t.modeProps)r[a]=t.modeProps[a];return r}var Tt={};function At(e,t){var n=Tt.hasOwnProperty(e)?Tt[e]:Tt[e]={};F(t,n)}function Ot(e,t){if(!0===t)return t;if(e.copyState)return e.copyState(t);var n={};for(var r in t){var i=t[r];i instanceof Array&&(i=i.concat([])),n[r]=i}return n}function Et(e,t){for(var n;e.innerMode&&(n=e.innerMode(t))&&n.mode!=e;)t=n.state,e=n.mode;return n||{mode:e,state:t}}function Nt(e,t,n){return!e.startState||e.startState(t,n)}var Pt=function(e,t,n){this.pos=this.start=0,this.string=e,this.tabSize=t||8,this.lastColumnPos=this.lastColumnValue=0,this.lineStart=0,this.lineOracle=n};Pt.prototype.eol=function(){return this.pos>=this.string.length},Pt.prototype.sol=function(){return this.pos==this.lineStart},Pt.prototype.peek=function(){return this.string.charAt(this.pos)||void 0},Pt.prototype.next=function(){if(this.post},Pt.prototype.eatSpace=function(){for(var e=this.pos;/[\s\u00a0]/.test(this.string.charAt(this.pos));)++this.pos;return this.pos>e},Pt.prototype.skipToEnd=function(){this.pos=this.string.length},Pt.prototype.skipTo=function(e){var t=this.string.indexOf(e,this.pos);if(t>-1)return this.pos=t,!0},Pt.prototype.backUp=function(e){this.pos-=e},Pt.prototype.column=function(){return this.lastColumnPos0?null:(r&&!1!==t&&(this.pos+=r[0].length),r)}var i=function(e){return n?e.toLowerCase():e},o=this.string.substr(this.pos,e.length);if(i(o)==i(e))return!1!==t&&(this.pos+=e.length),!0},Pt.prototype.current=function(){return this.string.slice(this.start,this.pos)},Pt.prototype.hideFirstChars=function(e,t){this.lineStart+=e;try{return t()}finally{this.lineStart-=e}},Pt.prototype.lookAhead=function(e){var t=this.lineOracle;return t&&t.lookAhead(e)},Pt.prototype.baseToken=function(){var e=this.lineOracle;return e&&e.baseToken(this.pos)};var It=function(e,t){this.state=e,this.lookAhead=t},Rt=function(e,t,n,r){this.state=t,this.doc=e,this.line=n,this.maxLookAhead=r||0,this.baseTokens=null,this.baseTokenPos=1};function Bt(e,t,n,r){var i=[e.state.modeGen],o={};Ut(e,t.text,e.doc.mode,n,function(e,t){return i.push(e,t)},o,r);for(var a=n.state,l=function(r){n.baseTokens=i;var l=e.state.overlays[r],s=1,c=0;n.state=!0,Ut(e,t.text,l.mode,n,function(e,t){for(var n=s;ce&&i.splice(s,1,e,i[s+1],r),s+=2,c=Math.min(e,r)}if(t)if(l.opaque)i.splice(n,s-n,e,"overlay "+t),s=n+2;else for(;ne.options.maxHighlightLength&&Ot(e.doc.mode,r.state),o=Bt(e,t,r);i&&(r.state=i),t.stateAfter=r.save(!i),t.styles=o.styles,o.classes?t.styleClasses=o.classes:t.styleClasses&&(t.styleClasses=null),n===e.doc.highlightFrontier&&(e.doc.modeFrontier=Math.max(e.doc.modeFrontier,++e.doc.highlightFrontier))}return t.styles}function Ft(e,t,n){var r=e.doc,i=e.display;if(!r.mode.startState)return new Rt(r,!0,t);var o=function(e,t,n){for(var r,i,o=e.doc,a=n?-1:t-(e.doc.mode.innerMode?1e3:100),l=t;l>a;--l){if(l<=o.first)return o.first;var s=le(o,l-1),c=s.stateAfter;if(c&&(!n||l+(c instanceof It?c.lookAhead:0)<=o.modeFrontier))return l;var u=z(s.text,null,e.options.tabSize);(null==i||r>u)&&(i=l-1,r=u)}return i}(e,t,n),a=o>r.first&&le(r,o-1).stateAfter,l=a?Rt.fromSaved(r,a,o):new Rt(r,Nt(r.mode),o);return r.iter(o,t,function(n){zt(e,n.text,l);var r=l.line;n.stateAfter=r==t-1||r%5==0||r>=i.viewFrom&&rt.start)return o}throw new Error("Mode "+e.name+" failed to advance stream.")}Rt.prototype.lookAhead=function(e){var t=this.doc.getLine(this.line+e);return null!=t&&e>this.maxLookAhead&&(this.maxLookAhead=e),t},Rt.prototype.baseToken=function(e){if(!this.baseTokens)return null;for(;this.baseTokens[this.baseTokenPos]<=e;)this.baseTokenPos+=2;var t=this.baseTokens[this.baseTokenPos+1];return{type:t&&t.replace(/( |^)overlay .*/,""),size:this.baseTokens[this.baseTokenPos]-e}},Rt.prototype.nextLine=function(){this.line++,this.maxLookAhead>0&&this.maxLookAhead--},Rt.fromSaved=function(e,t,n){return t instanceof It?new Rt(e,Ot(e.mode,t.state),n,t.lookAhead):new Rt(e,Ot(e.mode,t),n)},Rt.prototype.save=function(e){var t=!1!==e?Ot(this.doc.mode,this.state):this.state;return this.maxLookAhead>0?new It(t,this.maxLookAhead):t};var Ht=function(e,t,n){this.start=e.start,this.end=e.pos,this.string=e.current(),this.type=t||null,this.state=n};function Kt(e,t,n,r){var i,o=e.doc,a=o.mode;t=ke(o,t);var l,s=le(o,t.line),c=Ft(e,t.line,n),u=new Pt(s.text,e.options.tabSize,c);for(r&&(l=[]);(r||u.pose.options.maxHighlightLength?(l=!1,a&&zt(e,t,r,f.pos),f.pos=t.length,s=null):s=jt(_t(n,f,r.state,d),o),d){var h=d[0].name;h&&(s="m-"+(s?h+" "+s:h))}if(!l||u!=s){for(;c1&&!/ /.test(e))return e;for(var n=t,r="",i=0;ic&&f.from<=c);d++);if(f.to>=u)return e(n,r,i,o,a,l,s);e(n,r.slice(0,f.to-c),i,o,null,l,s),o=null,r=r.slice(f.to-c),c=f.to}}}function en(e,t,n,r){var i=!r&&n.widgetNode;i&&e.map.push(e.pos,e.pos+t,i),!r&&e.cm.display.input.needsContentAttribute&&(i||(i=e.content.appendChild(document.createElement("span"))),i.setAttribute("cm-marker",n.id)),i&&(e.cm.display.input.setUneditable(i),e.content.appendChild(i)),e.pos+=t,e.trailingSpace=!1}function tn(e,t,n){var r=e.markedSpans,i=e.text,o=0;if(r)for(var a,l,s,c,u,f,d,h=i.length,p=0,m=1,g="",v=0;;){if(v==p){s=c=u=f=l="",d=null,v=1/0;for(var y=[],b=void 0,x=0;xp||k.collapsed&&w.to==p&&w.from==p)?(null!=w.to&&w.to!=p&&v>w.to&&(v=w.to,c=""),k.className&&(s+=" "+k.className),k.css&&(l=(l?l+";":"")+k.css),k.startStyle&&w.from==p&&(u+=" "+k.startStyle),k.endStyle&&w.to==v&&(b||(b=[])).push(k.endStyle,w.to),k.title&&!f&&(f=k.title),k.collapsed&&(!d||Be(d.marker,k)<0)&&(d=w)):w.from>p&&v>w.from&&(v=w.from)}if(b)for(var C=0;C=h)break;for(var L=Math.min(h,v);;){if(g){var M=p+g.length;if(!d){var T=M>L?g.slice(0,L-p):g;t.addToken(t,T,a?a+s:s,u,p+T.length==v?c:"",f,l)}if(M>=L){g=g.slice(L-p),p=L;break}p=M,u=""}g=i.slice(o,o=n[m++]),a=Xt(n[m++],t.cm.options)}}else for(var A=1;An)return{map:e.measure.maps[i],cache:e.measure.caches[i],before:!0}}function On(e,t,n,r){return Pn(e,Nn(e,t),n,r)}function En(e,t){if(t>=e.display.viewFrom&&t=n.lineN&&t2&&o.push((s.bottom+c.top)/2-n.top)}}o.push(n.bottom-n.top)}}(e,t.view,t.rect),t.hasHeights=!0),(o=function(e,t,n,r){var i,o=Bn(t.map,n,r),s=o.node,c=o.start,u=o.end,f=o.collapse;if(3==s.nodeType){for(var d=0;d<4;d++){for(;c&&ie(t.line.text.charAt(o.coverStart+c));)--c;for(;o.coverStart+u1}(e))return t;var n=screen.logicalXDPI/screen.deviceXDPI,r=screen.logicalYDPI/screen.deviceYDPI;return{left:t.left*n,right:t.right*n,top:t.top*r,bottom:t.bottom*r}}(e.display.measure,i))}else{var h;c>0&&(f=r="right"),i=e.options.lineWrapping&&(h=s.getClientRects()).length>1?h["right"==r?h.length-1:0]:s.getBoundingClientRect()}if(a&&l<9&&!c&&(!i||!i.left&&!i.right)){var p=s.parentNode.getClientRects()[0];i=p?{left:p.left,right:p.left+tr(e.display),top:p.top,bottom:p.bottom}:Rn}for(var m=i.top-t.rect.top,g=i.bottom-t.rect.top,v=(m+g)/2,y=t.view.measure.heights,b=0;bt)&&(i=(o=s-l)-1,t>=s&&(a="right")),null!=i){if(r=e[c+2],l==s&&n==(r.insertLeft?"left":"right")&&(a=n),"left"==n&&0==i)for(;c&&e[c-2]==e[c-3]&&e[c-1].insertLeft;)r=e[2+(c-=3)],a="left";if("right"==n&&i==s-l)for(;c=0&&(n=e[i]).left==n.right;i--);return n}function Fn(e){if(e.measure&&(e.measure.cache={},e.measure.heights=null,e.rest))for(var t=0;t=r.text.length?(s=r.text.length,c="before"):s<=0&&(s=0,c="after"),!l)return a("before"==c?s-1:s,"before"==c);function u(e,t,n){var r=l[t],i=1==r.level;return a(n?e-1:e,i!=n)}var f=Ye(l,s,c),d=Xe,h=u(s,f,"before"==c);return null!=d&&(h.other=u(s,d,"before"!=c)),h}function $n(e,t){var n=0;t=ke(e.doc,t),e.options.lineWrapping||(n=tr(e.display)*t.ch);var r=le(e.doc,t.line),i=qe(r)+kn(e.display);return{left:n,right:n,top:i,bottom:i+r.height}}function Gn(e,t,n,r,i){var o=me(e,t,n);return o.xRel=i,r&&(o.outside=!0),o}function Xn(e,t,n){var r=e.doc;if((n+=e.display.viewOffset)<0)return Gn(r.first,0,null,!0,-1);var i=de(r,n),o=r.first+r.size-1;if(i>o)return Gn(r.first+r.size-1,le(r,o).text.length,null,!0,1);t<0&&(t=0);for(var a=le(r,i);;){var l=Qn(e,a,i,t,n),s=We(a,l.ch+(l.xRel>0?1:0));if(!s)return l;var c=s.find(1);if(c.line==i)return c;a=le(r,i=c.line)}}function Yn(e,t,n,r){r-=Kn(t);var i=t.text.length,o=ae(function(t){return Pn(e,n,t-1).bottom<=r},i,0);return i=ae(function(t){return Pn(e,n,t).top>r},o,i),{begin:o,end:i}}function Zn(e,t,n,r){n||(n=Nn(e,t));var i=jn(e,t,Pn(e,n,r),"line").top;return Yn(e,t,n,i)}function Jn(e,t,n,r){return!(e.bottom<=n)&&(e.top>n||(r?e.left:e.right)>t)}function Qn(e,t,n,r,i){i-=qe(t);var o=Nn(e,t),a=Kn(t),l=0,s=t.text.length,c=!0,u=Je(t,e.doc.direction);if(u){var f=(e.options.lineWrapping?function(e,t,n,r,i,o,a){var l=Yn(e,t,r,a),s=l.begin,c=l.end;/\s/.test(t.text.charAt(c-1))&&c--;for(var u=null,f=null,d=0;d=c||h.to<=s)){var p=1!=h.level,m=Pn(e,r,p?Math.min(c,h.to)-1:Math.max(s,h.from)).right,g=mg)&&(u=h,f=g)}}return u||(u=i[i.length-1]),u.fromc&&(u={from:u.from,to:c,level:u.level}),u}:function(e,t,n,r,i,o,a){var l=ae(function(l){var s=i[l],c=1!=s.level;return Jn(qn(e,me(n,c?s.to:s.from,c?"before":"after"),"line",t,r),o,a,!0)},0,i.length-1),s=i[l];if(l>0){var c=1!=s.level,u=qn(e,me(n,c?s.from:s.to,c?"after":"before"),"line",t,r);Jn(u,o,a,!0)&&u.top>a&&(s=i[l-1])}return s})(e,t,n,o,u,r,i);c=1!=f.level,l=c?f.from:f.to-1,s=c?f.to:f.from-1}var d,h,p=null,m=null,g=ae(function(t){var n=Pn(e,o,t);return n.top+=a,n.bottom+=a,!!Jn(n,r,i,!1)&&(n.top<=i&&n.left<=r&&(p=t,m=n),!0)},l,s),v=!1;if(m){var y=r-m.left=x.bottom}return g=oe(t.text,g,1),Gn(n,g,h,v,r-d)}function er(e){if(null!=e.cachedTextHeight)return e.cachedTextHeight;if(null==In){In=O("pre");for(var t=0;t<49;++t)In.appendChild(document.createTextNode("x")),In.appendChild(O("br"));In.appendChild(document.createTextNode("x"))}A(e.measure,In);var n=In.offsetHeight/50;return n>3&&(e.cachedTextHeight=n),T(e.measure),n||1}function tr(e){if(null!=e.cachedCharWidth)return e.cachedCharWidth;var t=O("span","xxxxxxxxxx"),n=O("pre",[t]);A(e.measure,n);var r=t.getBoundingClientRect(),i=(r.right-r.left)/10;return i>2&&(e.cachedCharWidth=i),i||10}function nr(e){for(var t=e.display,n={},r={},i=t.gutters.clientLeft,o=t.gutters.firstChild,a=0;o;o=o.nextSibling,++a)n[e.options.gutters[a]]=o.offsetLeft+o.clientLeft+i,r[e.options.gutters[a]]=o.clientWidth;return{fixedPos:rr(t),gutterTotalWidth:t.gutters.offsetWidth,gutterLeft:n,gutterWidth:r,wrapperWidth:t.wrapper.clientWidth}}function rr(e){return e.scroller.getBoundingClientRect().left-e.sizer.getBoundingClientRect().left}function ir(e){var t=er(e.display),n=e.options.lineWrapping,r=n&&Math.max(5,e.display.scroller.clientWidth/tr(e.display)-3);return function(i){if(Ue(e.doc,i))return 0;var o=0;if(i.widgets)for(var a=0;a=e.display.viewTo)return null;if((t-=e.display.viewFrom)<0)return null;for(var n=e.display.view,r=0;r=e.display.viewTo||l.to().linet||t==n&&a.to==t)&&(r(Math.max(a.from,t),Math.min(a.to,n),1==a.level?"rtl":"ltr",o),i=!0)}i||r(t,n,"ltr")}(m,n||0,null==r?d:r,function(e,t,i,f){var g="ltr"==i,v=h(e,g?"left":"right"),y=h(t-1,g?"right":"left"),b=null==n&&0==e,x=null==r&&t==d,w=0==f,k=!m||f==m.length-1;if(y.top-v.top<=3){var C=(c?b:x)&&w,S=(c?x:b)&&k,L=C?l:(g?v:y).left,M=S?s:(g?y:v).right;u(L,v.top,M-L,v.bottom)}else{var T,A,O,E;g?(T=c&&b&&w?l:v.left,A=c?s:p(e,i,"before"),O=c?l:p(t,i,"after"),E=c&&x&&k?s:y.right):(T=c?p(e,i,"before"):l,A=!c&&b&&w?s:v.right,O=!c&&x&&k?l:y.left,E=c?p(t,i,"after"):s),u(T,v.top,A-T,v.bottom),v.bottom0?t.blinker=setInterval(function(){return t.cursorDiv.style.visibility=(n=!n)?"":"hidden"},e.options.cursorBlinkRate):e.options.cursorBlinkRate<0&&(t.cursorDiv.style.visibility="hidden")}}function pr(e){e.state.focused||(e.display.input.focus(),gr(e))}function mr(e){e.state.delayingBlurEvent=!0,setTimeout(function(){e.state.delayingBlurEvent&&(e.state.delayingBlurEvent=!1,vr(e))},100)}function gr(e,t){e.state.delayingBlurEvent&&(e.state.delayingBlurEvent=!1),"nocursor"!=e.options.readOnly&&(e.state.focused||(rt(e,"focus",e,t),e.state.focused=!0,I(e.display.wrapper,"CodeMirror-focused"),e.curOp||e.display.selForContextMenu==e.doc.sel||(e.display.input.reset(),s&&setTimeout(function(){return e.display.input.reset(!0)},20)),e.display.input.receivedFocus()),hr(e))}function vr(e,t){e.state.delayingBlurEvent||(e.state.focused&&(rt(e,"blur",e,t),e.state.focused=!1,M(e.display.wrapper,"CodeMirror-focused")),clearInterval(e.display.blinker),setTimeout(function(){e.state.focused||(e.display.shift=!1)},150))}function yr(e){for(var t=e.display,n=t.lineDiv.offsetTop,r=0;r.005||u<-.005)&&(ue(i.line,o),br(i.line),i.rest))for(var f=0;f=a&&(o=de(t,qe(le(t,s))-e.wrapper.clientHeight),a=s)}return{from:o,to:Math.max(a,o+1)}}function wr(e){var t=e.display,n=t.view;if(t.alignWidgets||t.gutters.firstChild&&e.options.fixedGutter){for(var r=rr(t)-t.scroller.scrollLeft+e.doc.scrollLeft,i=t.gutters.offsetWidth,o=r+"px",a=0;ao&&(t.bottom=t.top+o);var l=e.doc.height+Cn(n),s=t.topl-r;if(t.topi+o){var u=Math.min(t.top,(c?l:t.bottom)-o);u!=i&&(a.scrollTop=u)}var f=e.curOp&&null!=e.curOp.scrollLeft?e.curOp.scrollLeft:n.scroller.scrollLeft,d=Mn(e)-(e.options.fixedGutter?n.gutters.offsetWidth:0),h=t.right-t.left>d;return h&&(t.right=t.left+d),t.left<10?a.scrollLeft=0:t.leftd+f-3&&(a.scrollLeft=t.right+(h?0:10)-d),a}function Sr(e,t){null!=t&&(Tr(e),e.curOp.scrollTop=(null==e.curOp.scrollTop?e.doc.scrollTop:e.curOp.scrollTop)+t)}function Lr(e){Tr(e);var t=e.getCursor();e.curOp.scrollToPos={from:t,to:t,margin:e.options.cursorScrollMargin}}function Mr(e,t,n){null==t&&null==n||Tr(e),null!=t&&(e.curOp.scrollLeft=t),null!=n&&(e.curOp.scrollTop=n)}function Tr(e){var t=e.curOp.scrollToPos;if(t){e.curOp.scrollToPos=null;var n=$n(e,t.from),r=$n(e,t.to);Ar(e,n,r,t.margin)}}function Ar(e,t,n,r){var i=Cr(e,{left:Math.min(t.left,n.left),top:Math.min(t.top,n.top)-r,right:Math.max(t.right,n.right),bottom:Math.max(t.bottom,n.bottom)+r});Mr(e,i.scrollLeft,i.scrollTop)}function Or(e,t){Math.abs(e.doc.scrollTop-t)<2||(n||li(e,{top:t}),Er(e,t,!0),n&&li(e),ni(e,100))}function Er(e,t,n){t=Math.min(e.display.scroller.scrollHeight-e.display.scroller.clientHeight,t),(e.display.scroller.scrollTop!=t||n)&&(e.doc.scrollTop=t,e.display.scrollbars.setScrollTop(t),e.display.scroller.scrollTop!=t&&(e.display.scroller.scrollTop=t))}function Nr(e,t,n,r){t=Math.min(t,e.display.scroller.scrollWidth-e.display.scroller.clientWidth),(n?t==e.doc.scrollLeft:Math.abs(e.doc.scrollLeft-t)<2)&&!r||(e.doc.scrollLeft=t,wr(e),e.display.scroller.scrollLeft!=t&&(e.display.scroller.scrollLeft=t),e.display.scrollbars.setScrollLeft(t))}function Pr(e){var t=e.display,n=t.gutters.offsetWidth,r=Math.round(e.doc.height+Cn(e.display));return{clientHeight:t.scroller.clientHeight,viewHeight:t.wrapper.clientHeight,scrollWidth:t.scroller.scrollWidth,clientWidth:t.scroller.clientWidth,viewWidth:t.wrapper.clientWidth,barLeft:e.options.fixedGutter?n:0,docHeight:r,scrollHeight:r+Ln(e)+t.barHeight,nativeBarWidth:t.nativeBarWidth,gutterWidth:n}}var Ir=function(e,t,n){this.cm=n;var r=this.vert=O("div",[O("div",null,null,"min-width: 1px")],"CodeMirror-vscrollbar"),i=this.horiz=O("div",[O("div",null,null,"height: 100%; min-height: 1px")],"CodeMirror-hscrollbar");r.tabIndex=i.tabIndex=-1,e(r),e(i),et(r,"scroll",function(){r.clientHeight&&t(r.scrollTop,"vertical")}),et(i,"scroll",function(){i.clientWidth&&t(i.scrollLeft,"horizontal")}),this.checkedZeroWidth=!1,a&&l<8&&(this.horiz.style.minHeight=this.vert.style.minWidth="18px")};Ir.prototype.update=function(e){var t=e.scrollWidth>e.clientWidth+1,n=e.scrollHeight>e.clientHeight+1,r=e.nativeBarWidth;if(n){this.vert.style.display="block",this.vert.style.bottom=t?r+"px":"0";var i=e.viewHeight-(t?r:0);this.vert.firstChild.style.height=Math.max(0,e.scrollHeight-e.clientHeight+i)+"px"}else this.vert.style.display="",this.vert.firstChild.style.height="0";if(t){this.horiz.style.display="block",this.horiz.style.right=n?r+"px":"0",this.horiz.style.left=e.barLeft+"px";var o=e.viewWidth-e.barLeft-(n?r:0);this.horiz.firstChild.style.width=Math.max(0,e.scrollWidth-e.clientWidth+o)+"px"}else this.horiz.style.display="",this.horiz.firstChild.style.width="0";return!this.checkedZeroWidth&&e.clientHeight>0&&(0==r&&this.zeroWidthHack(),this.checkedZeroWidth=!0),{right:n?r:0,bottom:t?r:0}},Ir.prototype.setScrollLeft=function(e){this.horiz.scrollLeft!=e&&(this.horiz.scrollLeft=e),this.disableHoriz&&this.enableZeroWidthBar(this.horiz,this.disableHoriz,"horiz")},Ir.prototype.setScrollTop=function(e){this.vert.scrollTop!=e&&(this.vert.scrollTop=e),this.disableVert&&this.enableZeroWidthBar(this.vert,this.disableVert,"vert")},Ir.prototype.zeroWidthHack=function(){var e=y&&!h?"12px":"18px";this.horiz.style.height=this.vert.style.width=e,this.horiz.style.pointerEvents=this.vert.style.pointerEvents="none",this.disableHoriz=new W,this.disableVert=new W},Ir.prototype.enableZeroWidthBar=function(e,t,n){e.style.pointerEvents="auto",t.set(1e3,function r(){var i=e.getBoundingClientRect(),o="vert"==n?document.elementFromPoint(i.right-1,(i.top+i.bottom)/2):document.elementFromPoint((i.right+i.left)/2,i.bottom-1);o!=e?e.style.pointerEvents="none":t.set(1e3,r)})},Ir.prototype.clear=function(){var e=this.horiz.parentNode;e.removeChild(this.horiz),e.removeChild(this.vert)};var Rr=function(){};function Br(e,t){t||(t=Pr(e));var n=e.display.barWidth,r=e.display.barHeight;Dr(e,t);for(var i=0;i<4&&n!=e.display.barWidth||r!=e.display.barHeight;i++)n!=e.display.barWidth&&e.options.lineWrapping&&yr(e),Dr(e,Pr(e)),n=e.display.barWidth,r=e.display.barHeight}function Dr(e,t){var n=e.display,r=n.scrollbars.update(t);n.sizer.style.paddingRight=(n.barWidth=r.right)+"px",n.sizer.style.paddingBottom=(n.barHeight=r.bottom)+"px",n.heightForcer.style.borderBottom=r.bottom+"px solid transparent",r.right&&r.bottom?(n.scrollbarFiller.style.display="block",n.scrollbarFiller.style.height=r.bottom+"px",n.scrollbarFiller.style.width=r.right+"px"):n.scrollbarFiller.style.display="",r.bottom&&e.options.coverGutterNextToScrollbar&&e.options.fixedGutter?(n.gutterFiller.style.display="block",n.gutterFiller.style.height=r.bottom+"px",n.gutterFiller.style.width=t.gutterWidth+"px"):n.gutterFiller.style.display=""}Rr.prototype.update=function(){return{bottom:0,right:0}},Rr.prototype.setScrollLeft=function(){},Rr.prototype.setScrollTop=function(){},Rr.prototype.clear=function(){};var Fr={native:Ir,null:Rr};function zr(e){e.display.scrollbars&&(e.display.scrollbars.clear(),e.display.scrollbars.addClass&&M(e.display.wrapper,e.display.scrollbars.addClass)),e.display.scrollbars=new Fr[e.options.scrollbarStyle](function(t){e.display.wrapper.insertBefore(t,e.display.scrollbarFiller),et(t,"mousedown",function(){e.state.focused&&setTimeout(function(){return e.display.input.focus()},0)}),t.setAttribute("cm-not-content","true")},function(t,n){"horizontal"==n?Nr(e,t):Or(e,t)},e),e.display.scrollbars.addClass&&I(e.display.wrapper,e.display.scrollbars.addClass)}var Wr=0;function _r(e){e.curOp={cm:e,viewChanged:!1,startHeight:e.doc.height,forceUpdate:!1,updateInput:null,typing:!1,changeObjs:null,cursorActivityHandlers:null,cursorActivityCalled:0,selectionChanged:!1,updateMaxLine:!1,scrollLeft:null,scrollTop:null,scrollToPos:null,focus:!1,id:++Wr},function(e){on?on.ops.push(e):e.ownsGroup=on={ops:[e],delayedCallbacks:[]}}(e.curOp)}function Hr(e){var t=e.curOp;!function(e,t){var n=e.ownsGroup;if(n)try{!function(e){var t=e.delayedCallbacks,n=0;do{for(;n=n.viewTo)||n.maxLineChanged&&t.options.lineWrapping,e.update=e.mustUpdate&&new ii(t,e.mustUpdate&&{top:e.scrollTop,ensure:e.scrollToPos},e.forceUpdate)}function jr(e){e.updatedDisplay=e.mustUpdate&&oi(e.cm,e.update)}function Ur(e){var t=e.cm,n=t.display;e.updatedDisplay&&yr(t),e.barMeasure=Pr(t),n.maxLineChanged&&!t.options.lineWrapping&&(e.adjustWidthTo=On(t,n.maxLine,n.maxLine.text.length).left+3,t.display.sizerWidth=e.adjustWidthTo,e.barMeasure.scrollWidth=Math.max(n.scroller.clientWidth,n.sizer.offsetLeft+e.adjustWidthTo+Ln(t)+t.display.barWidth),e.maxScrollLeft=Math.max(0,n.sizer.offsetLeft+e.adjustWidthTo-Mn(t))),(e.updatedDisplay||e.selectionChanged)&&(e.preparedSelection=n.input.prepareSelection())}function Vr(e){var t=e.cm;null!=e.adjustWidthTo&&(t.display.sizer.style.minWidth=e.adjustWidthTo+"px",e.maxScrollLeft1&&(a=!0)),null!=c.scrollLeft&&(Nr(e,c.scrollLeft),Math.abs(e.doc.scrollLeft-f)>1&&(a=!0)),!a)break}return i}(t,ke(r,e.scrollToPos.from),ke(r,e.scrollToPos.to),e.scrollToPos.margin);!function(e,t){if(!it(e,"scrollCursorIntoView")){var n=e.display,r=n.sizer.getBoundingClientRect(),i=null;if(t.top+r.top<0?i=!0:t.bottom+r.top>(window.innerHeight||document.documentElement.clientHeight)&&(i=!1),null!=i&&!p){var o=O("div","​",null,"position: absolute;\n top: "+(t.top-n.viewOffset-kn(e.display))+"px;\n height: "+(t.bottom-t.top+Ln(e)+n.barHeight)+"px;\n left: "+t.left+"px; width: "+Math.max(2,t.right-t.left)+"px;");e.display.lineSpace.appendChild(o),o.scrollIntoView(i),e.display.lineSpace.removeChild(o)}}}(t,i)}var o=e.maybeHiddenMarkers,a=e.maybeUnhiddenMarkers;if(o)for(var l=0;lt)&&(i.updateLineNumbers=t),e.curOp.viewChanged=!0,t>=i.viewTo)Le&&Ke(e.doc,t)i.viewFrom?Qr(e):(i.viewFrom+=r,i.viewTo+=r);else if(t<=i.viewFrom&&n>=i.viewTo)Qr(e);else if(t<=i.viewFrom){var o=ei(e,n,n+r,1);o?(i.view=i.view.slice(o.index),i.viewFrom=o.lineN,i.viewTo+=r):Qr(e)}else if(n>=i.viewTo){var a=ei(e,t,t,-1);a?(i.view=i.view.slice(0,a.index),i.viewTo=a.lineN):Qr(e)}else{var l=ei(e,t,t,-1),s=ei(e,n,n+r,1);l&&s?(i.view=i.view.slice(0,l.index).concat(rn(e,l.lineN,s.lineN)).concat(i.view.slice(s.index)),i.viewTo+=r):Qr(e)}var c=i.externalMeasured;c&&(n=i.lineN&&t=r.viewTo)){var o=r.view[lr(e,t)];if(null!=o.node){var a=o.changes||(o.changes=[]);-1==_(a,n)&&a.push(n)}}}function Qr(e){e.display.viewFrom=e.display.viewTo=e.doc.first,e.display.view=[],e.display.viewOffset=0}function ei(e,t,n,r){var i,o=lr(e,t),a=e.display.view;if(!Le||n==e.doc.first+e.doc.size)return{index:o,lineN:n};for(var l=e.display.viewFrom,s=0;s0){if(o==a.length-1)return null;i=l+a[o].size-t,o++}else i=l-t;t+=i,n+=i}for(;Ke(e.doc,n)!=n;){if(o==(r<0?0:a.length-1))return null;n+=r*a[o-(r<0?1:0)].size,o+=r}return{index:o,lineN:n}}function ti(e){for(var t=e.display.view,n=0,r=0;r=e.display.viewTo)){var n=+new Date+e.options.workTime,r=Ft(e,t.highlightFrontier),i=[];t.iter(r.line,Math.min(t.first+t.size,e.display.viewTo+500),function(o){if(r.line>=e.display.viewFrom){var a=o.styles,l=o.text.length>e.options.maxHighlightLength?Ot(t.mode,r.state):null,s=Bt(e,o,r,!0);l&&(r.state=l),o.styles=s.styles;var c=o.styleClasses,u=s.classes;u?o.styleClasses=u:c&&(o.styleClasses=null);for(var f=!a||a.length!=o.styles.length||c!=u&&(!c||!u||c.bgClass!=u.bgClass||c.textClass!=u.textClass),d=0;!f&&dn)return ni(e,e.options.workDelay),!0}),t.highlightFrontier=r.line,t.modeFrontier=Math.max(t.modeFrontier,r.line),i.length&&$r(e,function(){for(var t=0;t=n.viewFrom&&t.visible.to<=n.viewTo&&(null==n.updateLineNumbers||n.updateLineNumbers>=n.viewTo)&&n.renderedView==n.view&&0==ti(e))return!1;kr(e)&&(Qr(e),t.dims=nr(e));var i=r.first+r.size,o=Math.max(t.visible.from-e.options.viewportMargin,r.first),a=Math.min(i,t.visible.to+e.options.viewportMargin);n.viewFroma&&n.viewTo-a<20&&(a=Math.min(i,n.viewTo)),Le&&(o=Ke(e.doc,o),a=je(e.doc,a));var l=o!=n.viewFrom||a!=n.viewTo||n.lastWrapHeight!=t.wrapperHeight||n.lastWrapWidth!=t.wrapperWidth;!function(e,t,n){var r=e.display;0==r.view.length||t>=r.viewTo||n<=r.viewFrom?(r.view=rn(e,t,n),r.viewFrom=t):(r.viewFrom>t?r.view=rn(e,t,r.viewFrom).concat(r.view):r.viewFromn&&(r.view=r.view.slice(0,lr(e,n)))),r.viewTo=n}(e,o,a),n.viewOffset=qe(le(e.doc,n.viewFrom)),e.display.mover.style.top=n.viewOffset+"px";var c=ti(e);if(!l&&0==c&&!t.force&&n.renderedView==n.view&&(null==n.updateLineNumbers||n.updateLineNumbers>=n.viewTo))return!1;var u=function(e){if(e.hasFocus())return null;var t=P();if(!t||!N(e.display.lineDiv,t))return null;var n={activeElt:t};if(window.getSelection){var r=window.getSelection();r.anchorNode&&r.extend&&N(e.display.lineDiv,r.anchorNode)&&(n.anchorNode=r.anchorNode,n.anchorOffset=r.anchorOffset,n.focusNode=r.focusNode,n.focusOffset=r.focusOffset)}return n}(e);return c>4&&(n.lineDiv.style.display="none"),function(e,t,n){var r=e.display,i=e.options.lineNumbers,o=r.lineDiv,a=o.firstChild;function l(t){var n=t.nextSibling;return s&&y&&e.display.currentWheelTarget==t?t.style.display="none":t.parentNode.removeChild(t),n}for(var c=r.view,u=r.viewFrom,f=0;f-1&&(h=!1),cn(e,d,u,n)),h&&(T(d.lineNumber),d.lineNumber.appendChild(document.createTextNode(pe(e.options,u)))),a=d.node.nextSibling}else{var p=gn(e,d,u,n);o.insertBefore(p,a)}u+=d.size}for(;a;)a=l(a)}(e,n.updateLineNumbers,t.dims),c>4&&(n.lineDiv.style.display=""),n.renderedView=n.view,function(e){if(e&&e.activeElt&&e.activeElt!=P()&&(e.activeElt.focus(),e.anchorNode&&N(document.body,e.anchorNode)&&N(document.body,e.focusNode))){var t=window.getSelection(),n=document.createRange();n.setEnd(e.anchorNode,e.anchorOffset),n.collapse(!1),t.removeAllRanges(),t.addRange(n),t.extend(e.focusNode,e.focusOffset)}}(u),T(n.cursorDiv),T(n.selectionDiv),n.gutters.style.height=n.sizer.style.minHeight=0,l&&(n.lastWrapHeight=t.wrapperHeight,n.lastWrapWidth=t.wrapperWidth,ni(e,400)),n.updateLineNumbers=null,!0}function ai(e,t){for(var n=t.viewport,r=!0;(r&&e.options.lineWrapping&&t.oldDisplayWidth!=Mn(e)||(n&&null!=n.top&&(n={top:Math.min(e.doc.height+Cn(e.display)-Tn(e),n.top)}),t.visible=xr(e.display,e.doc,n),!(t.visible.from>=e.display.viewFrom&&t.visible.to<=e.display.viewTo)))&&oi(e,t);r=!1){yr(e);var i=Pr(e);sr(e),Br(e,i),ci(e,i),t.force=!1}t.signal(e,"update",e),e.display.viewFrom==e.display.reportedViewFrom&&e.display.viewTo==e.display.reportedViewTo||(t.signal(e,"viewportChange",e,e.display.viewFrom,e.display.viewTo),e.display.reportedViewFrom=e.display.viewFrom,e.display.reportedViewTo=e.display.viewTo)}function li(e,t){var n=new ii(e,t);if(oi(e,n)){yr(e),ai(e,n);var r=Pr(e);sr(e),Br(e,r),ci(e,r),n.finish()}}function si(e){var t=e.display.gutters.offsetWidth;e.display.sizer.style.marginLeft=t+"px"}function ci(e,t){e.display.sizer.style.minHeight=t.docHeight+"px",e.display.heightForcer.style.top=t.docHeight+"px",e.display.gutters.style.height=t.docHeight+e.display.barHeight+Ln(e)+"px"}function ui(e){var t=e.display.gutters,n=e.options.gutters;T(t);for(var r=0;r-1&&!e.lineNumbers&&(e.gutters=e.gutters.slice(0),e.gutters.splice(t,1))}ii.prototype.signal=function(e,t){at(e,t)&&this.events.push(arguments)},ii.prototype.finish=function(){for(var e=0;el.clientWidth,u=l.scrollHeight>l.clientHeight;if(i&&c||o&&u){if(o&&y&&s)e:for(var d=t.target,h=a.view;d!=l;d=d.parentNode)for(var p=0;p=0&&ge(e,r.to())<=0)return n}return-1};var yi=function(e,t){this.anchor=e,this.head=t};function bi(e,t){var n=e[t];e.sort(function(e,t){return ge(e.from(),t.from())}),t=_(e,n);for(var r=1;r=0){var a=xe(o.from(),i.from()),l=be(o.to(),i.to()),s=o.empty()?i.from()==i.head:o.from()==o.head;r<=t&&--t,e.splice(--r,2,new yi(s?l:a,s?a:l))}}return new vi(e,t)}function xi(e,t){return new vi([new yi(e,t||e)],0)}function wi(e){return e.text?me(e.from.line+e.text.length-1,X(e.text).length+(1==e.text.length?e.from.ch:0)):e.to}function ki(e,t){if(ge(e,t.from)<0)return e;if(ge(e,t.to)<=0)return wi(t);var n=e.line+t.text.length-(t.to.line-t.from.line)-1,r=e.ch;return e.line==t.to.line&&(r+=wi(t).ch-t.to.ch),me(n,r)}function Ci(e,t){for(var n=[],r=0;r1&&e.remove(l.line+1,p-1),e.insert(l.line+1,v)}ln(e,"change",e,t)}function Oi(e,t,n){!function e(r,i,o){if(r.linked)for(var a=0;al-(e.cm?e.cm.options.historyEventDelay:500)||"*"==t.origin.charAt(0)))&&(o=function(e,t){return t?(Ri(e.done),X(e.done)):e.done.length&&!X(e.done).ranges?X(e.done):e.done.length>1&&!e.done[e.done.length-2].ranges?(e.done.pop(),X(e.done)):void 0}(i,i.lastOp==r)))a=X(o.changes),0==ge(t.from,t.to)&&0==ge(t.from,a.to)?a.to=wi(t):o.changes.push(Ii(e,t));else{var s=X(i.done);for(s&&s.ranges||Fi(e.sel,i.done),o={changes:[Ii(e,t)],generation:i.generation},i.done.push(o);i.done.length>i.undoDepth;)i.done.shift(),i.done[0].ranges||i.done.shift()}i.done.push(n),i.generation=++i.maxGeneration,i.lastModTime=i.lastSelTime=l,i.lastOp=i.lastSelOp=r,i.lastOrigin=i.lastSelOrigin=t.origin,a||rt(e,"historyAdded")}function Di(e,t,n,r){var i=e.history,o=r&&r.origin;n==i.lastSelOp||o&&i.lastSelOrigin==o&&(i.lastModTime==i.lastSelTime&&i.lastOrigin==o||function(e,t,n,r){var i=t.charAt(0);return"*"==i||"+"==i&&n.ranges.length==r.ranges.length&&n.somethingSelected()==r.somethingSelected()&&new Date-e.history.lastSelTime<=(e.cm?e.cm.options.historyEventDelay:500)}(e,o,X(i.done),t))?i.done[i.done.length-1]=t:Fi(t,i.done),i.lastSelTime=+new Date,i.lastSelOrigin=o,i.lastSelOp=n,r&&!1!==r.clearRedo&&Ri(i.undone)}function Fi(e,t){var n=X(t);n&&n.ranges&&n.equals(e)||t.push(e)}function zi(e,t,n,r){var i=t["spans_"+e.id],o=0;e.iter(Math.max(e.first,n),Math.min(e.first+e.size,r),function(n){n.markedSpans&&((i||(i=t["spans_"+e.id]={}))[o]=n.markedSpans),++o})}function Wi(e){if(!e)return null;for(var t,n=0;n-1&&(X(l)[f]=c[f],delete c[f])}}}return r}function Ki(e,t,n,r){if(r){var i=e.anchor;if(n){var o=ge(t,i)<0;o!=ge(n,i)<0?(i=t,t=n):o!=ge(t,n)<0&&(t=n)}return new yi(i,t)}return new yi(n||t,t)}function ji(e,t,n,r,i){null==i&&(i=e.cm&&(e.cm.display.shift||e.extend)),Gi(e,new vi([Ki(e.sel.primary(),t,n,i)],0),r)}function Ui(e,t,n){for(var r=[],i=e.cm&&(e.cm.display.shift||e.extend),o=0;o=t.ch:l.to>t.ch))){if(i&&(rt(s,"beforeCursorEnter"),s.explicitlyCleared)){if(o.markedSpans){--a;continue}break}if(!s.atomic)continue;if(n){var c=s.find(r<0?1:-1),u=void 0;if((r<0?s.inclusiveRight:s.inclusiveLeft)&&(c=to(e,c,-r,c&&c.line==t.line?o:null)),c&&c.line==t.line&&(u=ge(c,n))&&(r<0?u<0:u>0))return Qi(e,c,t,r,i)}var f=s.find(r<0?-1:1);return(r<0?s.inclusiveLeft:s.inclusiveRight)&&(f=to(e,f,r,f.line==t.line?o:null)),f?Qi(e,f,t,r,i):null}}return t}function eo(e,t,n,r,i){var o=r||1,a=Qi(e,t,n,o,i)||!i&&Qi(e,t,n,o,!0)||Qi(e,t,n,-o,i)||!i&&Qi(e,t,n,-o,!0);return a||(e.cantEdit=!0,me(e.first,0))}function to(e,t,n,r){return n<0&&0==t.ch?t.line>e.first?ke(e,me(t.line-1)):null:n>0&&t.ch==(r||le(e,t.line)).text.length?t.line0)){var u=[s,1],f=ge(c.from,l.from),d=ge(c.to,l.to);(f<0||!a.inclusiveLeft&&!f)&&u.push({from:c.from,to:l.from}),(d>0||!a.inclusiveRight&&!d)&&u.push({from:l.to,to:c.to}),i.splice.apply(i,u),s+=u.length-3}}return i}(e,t.from,t.to);if(r)for(var i=r.length-1;i>=0;--i)oo(e,{from:r[i].from,to:r[i].to,text:i?[""]:t.text,origin:t.origin});else oo(e,t)}}function oo(e,t){if(1!=t.text.length||""!=t.text[0]||0!=ge(t.from,t.to)){var n=Ci(e,t);Bi(e,t,n,e.cm?e.cm.curOp.id:NaN),so(e,t,n,Oe(e,t));var r=[];Oi(e,function(e,n){n||-1!=_(r,e.history)||(ho(e.history,t),r.push(e.history)),so(e,t,null,Oe(e,t))})}}function ao(e,t,n){var r=e.cm&&e.cm.state.suppressEdits;if(!r||n){for(var i,o=e.history,a=e.sel,l="undo"==t?o.done:o.undone,s="undo"==t?o.undone:o.done,c=0;c=0;--h){var p=d(h);if(p)return p.v}}}}function lo(e,t){if(0!=t&&(e.first+=t,e.sel=new vi(Y(e.sel.ranges,function(e){return new yi(me(e.anchor.line+t,e.anchor.ch),me(e.head.line+t,e.head.ch))}),e.sel.primIndex),e.cm)){Zr(e.cm,e.first,e.first-t,t);for(var n=e.cm.display,r=n.viewFrom;re.lastLine())){if(t.from.lineo&&(t={from:t.from,to:me(o,le(e,o).text.length),text:[t.text[0]],origin:t.origin}),t.removed=se(e,t.from,t.to),n||(n=Ci(e,t)),e.cm?function(e,t,n){var r=e.doc,i=e.display,o=t.from,a=t.to,l=!1,s=o.line;e.options.lineWrapping||(s=fe(He(le(r,o.line))),r.iter(s,a.line+1,function(e){if(e==i.maxLine)return l=!0,!0})),r.sel.contains(t.from,t.to)>-1&&ot(e),Ai(r,t,n,ir(e)),e.options.lineWrapping||(r.iter(s,o.line+t.text.length,function(e){var t=$e(e);t>i.maxLineLength&&(i.maxLine=e,i.maxLineLength=t,i.maxLineChanged=!0,l=!1)}),l&&(e.curOp.updateMaxLine=!0)),function(e,t){if(e.modeFrontier=Math.min(e.modeFrontier,t),!(e.highlightFrontiern;r--){var i=le(e,r).stateAfter;if(i&&(!(i instanceof It)||r+i.lookAhead1||!(this.children[0]instanceof mo))){var l=[];this.collapse(l),this.children=[new mo(l)],this.children[0].parent=this}},collapse:function(e){for(var t=0;t50){for(var a=i.lines.length%25+25,l=a;l10);e.parent.maybeSpill()}},iterN:function(e,t,n){for(var r=0;r0||0==a&&!1!==o.clearWhenEmpty)return o;if(o.replacedWith&&(o.collapsed=!0,o.widgetNode=E("span",[o.replacedWith],"CodeMirror-widget"),r.handleMouseEvents||o.widgetNode.setAttribute("cm-ignore-events","true"),r.insertLeft&&(o.widgetNode.insertLeft=!0)),o.collapsed){if(_e(e,t.line,t,n,o)||t.line!=n.line&&_e(e,n.line,t,n,o))throw new Error("Inserting collapsed marker partially overlapping an existing one");Le=!0}o.addToHistory&&Bi(e,{from:t,to:n,origin:"markText"},e.sel,NaN);var l,s=t.line,c=e.cm;if(e.iter(s,n.line+1,function(e){c&&o.collapsed&&!c.options.lineWrapping&&He(e)==c.display.maxLine&&(l=!0),o.collapsed&&s!=t.line&&ue(e,0),function(e,t){e.markedSpans=e.markedSpans?e.markedSpans.concat([t]):[t],t.marker.attachLine(e)}(e,new Me(o,s==t.line?t.ch:null,s==n.line?n.ch:null)),++s}),o.collapsed&&e.iter(t.line,n.line+1,function(t){Ue(e,t)&&ue(t,0)}),o.clearOnEnter&&et(o,"beforeCursorEnter",function(){return o.clear()}),o.readOnly&&(Se=!0,(e.history.done.length||e.history.undone.length)&&e.clearHistory()),o.collapsed&&(o.id=++bo,o.atomic=!0),c){if(l&&(c.curOp.updateMaxLine=!0),o.collapsed)Zr(c,t.line,n.line+1);else if(o.className||o.title||o.startStyle||o.endStyle||o.css)for(var u=t.line;u<=n.line;u++)Jr(c,u,"text");o.atomic&&Zi(c.doc),ln(c,"markerAdded",c,o)}return o}xo.prototype.clear=function(){if(!this.explicitlyCleared){var e=this.doc.cm,t=e&&!e.curOp;if(t&&_r(e),at(this,"clear")){var n=this.find();n&&ln(this,"clear",n.from,n.to)}for(var r=null,i=null,o=0;oe.display.maxLineLength&&(e.display.maxLine=c,e.display.maxLineLength=u,e.display.maxLineChanged=!0)}null!=r&&e&&this.collapsed&&Zr(e,r,i+1),this.lines.length=0,this.explicitlyCleared=!0,this.atomic&&this.doc.cantEdit&&(this.doc.cantEdit=!1,e&&Zi(e.doc)),e&&ln(e,"markerCleared",e,this,r,i),t&&Hr(e),this.parent&&this.parent.clear()}},xo.prototype.find=function(e,t){var n,r;null==e&&"bookmark"==this.type&&(e=1);for(var i=0;i=0;s--)io(this,r[s]);l?$i(this,l):this.cm&&Lr(this.cm)}),undo:Yr(function(){ao(this,"undo")}),redo:Yr(function(){ao(this,"redo")}),undoSelection:Yr(function(){ao(this,"undo",!0)}),redoSelection:Yr(function(){ao(this,"redo",!0)}),setExtending:function(e){this.extend=e},getExtending:function(){return this.extend},historySize:function(){for(var e=this.history,t=0,n=0,r=0;r=e.ch)&&t.push(i.marker.parent||i.marker)}return t},findMarks:function(e,t,n){e=ke(this,e),t=ke(this,t);var r=[],i=e.line;return this.iter(e.line,t.line+1,function(o){var a=o.markedSpans;if(a)for(var l=0;l=s.to||null==s.from&&i!=e.line||null!=s.from&&i==t.line&&s.from>=t.ch||n&&!n(s.marker)||r.push(s.marker.parent||s.marker)}++i}),r},getAllMarks:function(){var e=[];return this.iter(function(t){var n=t.markedSpans;if(n)for(var r=0;re)return t=e,!0;e-=o,++n}),ke(this,me(n,t))},indexFromPos:function(e){var t=(e=ke(this,e)).ch;if(e.linet&&(t=e.from),null!=e.to&&e.to-1)return t.state.draggingText(e),void setTimeout(function(){return t.display.input.focus()},20);try{var u=e.dataTransfer.getData("Text");if(u){var f;if(t.state.draggingText&&!t.state.draggingText.copy&&(f=t.listSelections()),Xi(t.doc,xi(n,n)),f)for(var d=0;d=0;t--)co(e.doc,"",r[t].from,r[t].to,"+delete");Lr(e)})}function $o(e,t,n){var r=oe(e.text,t+n,n);return r<0||r>e.text.length?null:r}function Go(e,t,n){var r=$o(e,t.ch,n);return null==r?null:new me(t.line,r,n<0?"after":"before")}function Xo(e,t,n,r,i){if(e){var o=Je(n,t.doc.direction);if(o){var a,l=i<0?X(o):o[0],s=i<0==(1==l.level),c=s?"after":"before";if(l.level>0||"rtl"==t.doc.direction){var u=Nn(t,n);a=i<0?n.text.length-1:0;var f=Pn(t,u,a).top;a=ae(function(e){return Pn(t,u,e).top==f},i<0==(1==l.level)?l.from:l.to-1,a),"before"==c&&(a=$o(n,a,1))}else a=i<0?l.to:l.from;return new me(r,a,c)}}return new me(r,i<0?n.text.length:0,i<0?"before":"after")}zo.basic={Left:"goCharLeft",Right:"goCharRight",Up:"goLineUp",Down:"goLineDown",End:"goLineEnd",Home:"goLineStartSmart",PageUp:"goPageUp",PageDown:"goPageDown",Delete:"delCharAfter",Backspace:"delCharBefore","Shift-Backspace":"delCharBefore",Tab:"defaultTab","Shift-Tab":"indentAuto",Enter:"newlineAndIndent",Insert:"toggleOverwrite",Esc:"singleSelection"},zo.pcDefault={"Ctrl-A":"selectAll","Ctrl-D":"deleteLine","Ctrl-Z":"undo","Shift-Ctrl-Z":"redo","Ctrl-Y":"redo","Ctrl-Home":"goDocStart","Ctrl-End":"goDocEnd","Ctrl-Up":"goLineUp","Ctrl-Down":"goLineDown","Ctrl-Left":"goGroupLeft","Ctrl-Right":"goGroupRight","Alt-Left":"goLineStart","Alt-Right":"goLineEnd","Ctrl-Backspace":"delGroupBefore","Ctrl-Delete":"delGroupAfter","Ctrl-S":"save","Ctrl-F":"find","Ctrl-G":"findNext","Shift-Ctrl-G":"findPrev","Shift-Ctrl-F":"replace","Shift-Ctrl-R":"replaceAll","Ctrl-[":"indentLess","Ctrl-]":"indentMore","Ctrl-U":"undoSelection","Shift-Ctrl-U":"redoSelection","Alt-U":"redoSelection",fallthrough:"basic"},zo.emacsy={"Ctrl-F":"goCharRight","Ctrl-B":"goCharLeft","Ctrl-P":"goLineUp","Ctrl-N":"goLineDown","Alt-F":"goWordRight","Alt-B":"goWordLeft","Ctrl-A":"goLineStart","Ctrl-E":"goLineEnd","Ctrl-V":"goPageDown","Shift-Ctrl-V":"goPageUp","Ctrl-D":"delCharAfter","Ctrl-H":"delCharBefore","Alt-D":"delWordAfter","Alt-Backspace":"delWordBefore","Ctrl-K":"killLine","Ctrl-T":"transposeChars","Ctrl-O":"openLine"},zo.macDefault={"Cmd-A":"selectAll","Cmd-D":"deleteLine","Cmd-Z":"undo","Shift-Cmd-Z":"redo","Cmd-Y":"redo","Cmd-Home":"goDocStart","Cmd-Up":"goDocStart","Cmd-End":"goDocEnd","Cmd-Down":"goDocEnd","Alt-Left":"goGroupLeft","Alt-Right":"goGroupRight","Cmd-Left":"goLineLeft","Cmd-Right":"goLineRight","Alt-Backspace":"delGroupBefore","Ctrl-Alt-Backspace":"delGroupAfter","Alt-Delete":"delGroupAfter","Cmd-S":"save","Cmd-F":"find","Cmd-G":"findNext","Shift-Cmd-G":"findPrev","Cmd-Alt-F":"replace","Shift-Cmd-Alt-F":"replaceAll","Cmd-[":"indentLess","Cmd-]":"indentMore","Cmd-Backspace":"delWrappedLineLeft","Cmd-Delete":"delWrappedLineRight","Cmd-U":"undoSelection","Shift-Cmd-U":"redoSelection","Ctrl-Up":"goDocStart","Ctrl-Down":"goDocEnd",fallthrough:["basic","emacsy"]},zo.default=y?zo.macDefault:zo.pcDefault;var Yo={selectAll:no,singleSelection:function(e){return e.setSelection(e.getCursor("anchor"),e.getCursor("head"),j)},killLine:function(e){return qo(e,function(t){if(t.empty()){var n=le(e.doc,t.head.line).text.length;return t.head.ch==n&&t.head.line0)i=new me(i.line,i.ch+1),e.replaceRange(o.charAt(i.ch-1)+o.charAt(i.ch-2),me(i.line,i.ch-2),i,"+transpose");else if(i.line>e.doc.first){var a=le(e.doc,i.line-1).text;a&&(i=new me(i.line,1),e.replaceRange(o.charAt(0)+e.doc.lineSeparator()+a.charAt(a.length-1),me(i.line-1,a.length-1),i,"+transpose"))}n.push(new yi(i,i))}e.setSelections(n)})},newlineAndIndent:function(e){return $r(e,function(){for(var t=e.listSelections(),n=t.length-1;n>=0;n--)e.replaceRange(e.doc.lineSeparator(),t[n].anchor,t[n].head,"+input");t=e.listSelections();for(var r=0;r-1&&(ge((i=c.ranges[i]).from(),t)<0||t.xRel>0)&&(ge(i.to(),t)>0||t.xRel<0)?function(e,t,n,r){var i=e.display,o=!1,c=Gr(e,function(t){s&&(i.scroller.draggable=!1),e.state.draggingText=!1,nt(i.wrapper.ownerDocument,"mouseup",c),nt(i.wrapper.ownerDocument,"mousemove",u),nt(i.scroller,"dragstart",f),nt(i.scroller,"drop",c),o||(st(t),r.addNew||ji(e.doc,n,null,null,r.extend),s||a&&9==l?setTimeout(function(){i.wrapper.ownerDocument.body.focus(),i.input.focus()},20):i.input.focus())}),u=function(e){o=o||Math.abs(t.clientX-e.clientX)+Math.abs(t.clientY-e.clientY)>=10},f=function(){return o=!0};s&&(i.scroller.draggable=!0),e.state.draggingText=c,c.copy=!r.moveOnDrag,i.scroller.dragDrop&&i.scroller.dragDrop(),et(i.wrapper.ownerDocument,"mouseup",c),et(i.wrapper.ownerDocument,"mousemove",u),et(i.scroller,"dragstart",f),et(i.scroller,"drop",c),mr(e),setTimeout(function(){return i.input.focus()},20)}(e,r,t,o):function(e,t,n,r){var i=e.display,o=e.doc;st(t);var a,l,s=o.sel,c=s.ranges;if(r.addNew&&!r.extend?(l=o.sel.contains(n),a=l>-1?c[l]:new yi(n,n)):(a=o.sel.primary(),l=o.sel.primIndex),"rectangle"==r.unit)r.addNew||(a=new yi(n,n)),n=ar(e,t,!0,!0),l=-1;else{var u=da(e,n,r.unit);a=r.extend?Ki(a,u.anchor,u.head,r.extend):u}r.addNew?-1==l?(l=c.length,Gi(o,bi(c.concat([a]),l),{scroll:!1,origin:"*mouse"})):c.length>1&&c[l].empty()&&"char"==r.unit&&!r.extend?(Gi(o,bi(c.slice(0,l).concat(c.slice(l+1)),0),{scroll:!1,origin:"*mouse"}),s=o.sel):Vi(o,l,a,U):(l=0,Gi(o,new vi([a],0),U),s=o.sel);var f=n;function d(t){if(0!=ge(f,t))if(f=t,"rectangle"==r.unit){for(var i=[],c=e.options.tabSize,u=z(le(o,n.line).text,n.ch,c),d=z(le(o,t.line).text,t.ch,c),h=Math.min(u,d),p=Math.max(u,d),m=Math.min(n.line,t.line),g=Math.min(e.lastLine(),Math.max(n.line,t.line));m<=g;m++){var v=le(o,m).text,y=q(v,h,c);h==p?i.push(new yi(me(m,y),me(m,y))):v.length>y&&i.push(new yi(me(m,y),me(m,q(v,p,c))))}i.length||i.push(new yi(n,n)),Gi(o,bi(s.ranges.slice(0,l).concat(i),l),{origin:"*mouse",scroll:!1}),e.scrollIntoView(t)}else{var b,x=a,w=da(e,t,r.unit),k=x.anchor;ge(w.anchor,k)>0?(b=w.head,k=xe(x.from(),w.anchor)):(b=w.anchor,k=be(x.to(),w.head));var C=s.ranges.slice(0);C[l]=function(e,t){var n=t.anchor,r=t.head,i=le(e.doc,n.line);if(0==ge(n,r)&&n.sticky==r.sticky)return t;var o=Je(i);if(!o)return t;var a=Ye(o,n.ch,n.sticky),l=o[a];if(l.from!=n.ch&&l.to!=n.ch)return t;var s,c=a+(l.from==n.ch==(1!=l.level)?0:1);if(0==c||c==o.length)return t;if(r.line!=n.line)s=(r.line-n.line)*("ltr"==e.doc.direction?1:-1)>0;else{var u=Ye(o,r.ch,r.sticky),f=u-a||(r.ch-n.ch)*(1==l.level?-1:1);s=u==c-1||u==c?f<0:f>0}var d=o[c+(s?-1:0)],h=s==(1==d.level),p=h?d.from:d.to,m=h?"after":"before";return n.ch==p&&n.sticky==m?t:new yi(new me(n.line,p,m),r)}(e,new yi(ke(o,k),b)),Gi(o,bi(C,l),U)}}var h=i.wrapper.getBoundingClientRect(),p=0;function m(t){e.state.selectingText=!1,p=1/0,st(t),i.input.focus(),nt(i.wrapper.ownerDocument,"mousemove",g),nt(i.wrapper.ownerDocument,"mouseup",v),o.history.lastSelOrigin=null}var g=Gr(e,function(t){0!==t.buttons&&ht(t)?function t(n){var a=++p,l=ar(e,n,!0,"rectangle"==r.unit);if(l)if(0!=ge(l,f)){e.curOp.focus=P(),d(l);var s=xr(i,o);(l.line>=s.to||l.lineh.bottom?20:0;c&&setTimeout(Gr(e,function(){p==a&&(i.scroller.scrollTop+=c,t(n))}),50)}}(t):m(t)}),v=Gr(e,m);e.state.selectingText=v,et(i.wrapper.ownerDocument,"mousemove",g),et(i.wrapper.ownerDocument,"mouseup",v)}(e,r,t,o)}(t,r,o,e):dt(e)==n.scroller&&st(e):2==i?(r&&ji(t.doc,r),setTimeout(function(){return n.input.focus()},20)):3==i&&(C?ma(t,e):mr(t)))}}function da(e,t,n){if("char"==n)return new yi(t,t);if("word"==n)return e.findWordAt(t);if("line"==n)return new yi(me(t.line,0),ke(e.doc,me(t.line+1,0)));var r=n(e,t);return new yi(r.from,r.to)}function ha(e,t,n,r){var i,o;if(t.touches)i=t.touches[0].clientX,o=t.touches[0].clientY;else try{i=t.clientX,o=t.clientY}catch(t){return!1}if(i>=Math.floor(e.display.gutters.getBoundingClientRect().right))return!1;r&&st(t);var a=e.display,l=a.lineDiv.getBoundingClientRect();if(o>l.bottom||!at(e,n))return ut(t);o-=l.top-a.viewOffset;for(var s=0;s=i){var u=de(e.doc,o),f=e.options.gutters[s];return rt(e,n,e,u,f,t),ut(t)}}}function pa(e,t){return ha(e,t,"gutterClick",!0)}function ma(e,t){wn(e.display,t)||function(e,t){return!!at(e,"gutterContextMenu")&&ha(e,t,"gutterContextMenu",!1)}(e,t)||it(e,t,"contextmenu")||e.display.input.onContextMenu(t)}function ga(e){e.display.wrapper.className=e.display.wrapper.className.replace(/\s*cm-s-\S+/g,"")+e.options.theme.replace(/(^|\s)\s*/g," cm-s-"),Wn(e)}ua.prototype.compare=function(e,t,n){return this.time+400>e&&0==ge(t,this.pos)&&n==this.button};var va={toString:function(){return"CodeMirror.Init"}},ya={},ba={};function xa(e){ui(e),Zr(e),wr(e)}function wa(e,t,n){var r=n&&n!=va;if(!t!=!r){var i=e.display.dragFunctions,o=t?et:nt;o(e.display.scroller,"dragstart",i.start),o(e.display.scroller,"dragenter",i.enter),o(e.display.scroller,"dragover",i.over),o(e.display.scroller,"dragleave",i.leave),o(e.display.scroller,"drop",i.drop)}}function ka(e){e.options.lineWrapping?(I(e.display.wrapper,"CodeMirror-wrap"),e.display.sizer.style.minWidth="",e.display.sizerWidth=null):(M(e.display.wrapper,"CodeMirror-wrap"),Ge(e)),or(e),Zr(e),Wn(e),setTimeout(function(){return Br(e)},100)}function Ca(e,t){var r=this;if(!(this instanceof Ca))return new Ca(e,t);this.options=t=t?F(t):{},F(ya,t,!1),fi(t);var i=t.value;"string"==typeof i&&(i=new Mo(i,t.mode,null,t.lineSeparator,t.direction)),this.doc=i;var o=new Ca.inputStyles[t.inputStyle](this),c=this.display=new function(e,t,r){var i=this;this.input=r,i.scrollbarFiller=O("div",null,"CodeMirror-scrollbar-filler"),i.scrollbarFiller.setAttribute("cm-not-content","true"),i.gutterFiller=O("div",null,"CodeMirror-gutter-filler"),i.gutterFiller.setAttribute("cm-not-content","true"),i.lineDiv=E("div",null,"CodeMirror-code"),i.selectionDiv=O("div",null,null,"position: relative; z-index: 1"),i.cursorDiv=O("div",null,"CodeMirror-cursors"),i.measure=O("div",null,"CodeMirror-measure"),i.lineMeasure=O("div",null,"CodeMirror-measure"),i.lineSpace=E("div",[i.measure,i.lineMeasure,i.selectionDiv,i.cursorDiv,i.lineDiv],null,"position: relative; outline: none");var o=E("div",[i.lineSpace],"CodeMirror-lines");i.mover=O("div",[o],null,"position: relative"),i.sizer=O("div",[i.mover],"CodeMirror-sizer"),i.sizerWidth=null,i.heightForcer=O("div",null,null,"position: absolute; height: "+H+"px; width: 1px;"),i.gutters=O("div",null,"CodeMirror-gutters"),i.lineGutter=null,i.scroller=O("div",[i.sizer,i.heightForcer,i.gutters],"CodeMirror-scroll"),i.scroller.setAttribute("tabIndex","-1"),i.wrapper=O("div",[i.scrollbarFiller,i.gutterFiller,i.scroller],"CodeMirror"),a&&l<8&&(i.gutters.style.zIndex=-1,i.scroller.style.paddingRight=0),s||n&&v||(i.scroller.draggable=!0),e&&(e.appendChild?e.appendChild(i.wrapper):e(i.wrapper)),i.viewFrom=i.viewTo=t.first,i.reportedViewFrom=i.reportedViewTo=t.first,i.view=[],i.renderedView=null,i.externalMeasured=null,i.viewOffset=0,i.lastWrapHeight=i.lastWrapWidth=0,i.updateLineNumbers=null,i.nativeBarWidth=i.barHeight=i.barWidth=0,i.scrollbarsClipped=!1,i.lineNumWidth=i.lineNumInnerWidth=i.lineNumChars=null,i.alignWidgets=!1,i.cachedCharWidth=i.cachedTextHeight=i.cachedPaddingH=null,i.maxLine=null,i.maxLineLength=0,i.maxLineChanged=!1,i.wheelDX=i.wheelDY=i.wheelStartX=i.wheelStartY=null,i.shift=!1,i.selForContextMenu=null,i.activeTouch=null,r.init(i)}(e,i,o);for(var u in c.wrapper.CodeMirror=this,ui(this),ga(this),t.lineWrapping&&(this.display.wrapper.className+=" CodeMirror-wrap"),zr(this),this.state={keyMaps:[],overlays:[],modeGen:0,overwrite:!1,delayingBlurEvent:!1,focused:!1,suppressEdits:!1,pasteIncoming:!1,cutIncoming:!1,selectingText:!1,draggingText:!1,highlight:new W,keySeq:null,specialChars:null},t.autofocus&&!v&&c.input.focus(),a&&l<11&&setTimeout(function(){return r.display.input.reset(!0)},20),function(e){var t=e.display;et(t.scroller,"mousedown",Gr(e,fa)),et(t.scroller,"dblclick",a&&l<11?Gr(e,function(t){if(!it(e,t)){var n=ar(e,t);if(n&&!pa(e,t)&&!wn(e.display,t)){st(t);var r=e.findWordAt(n);ji(e.doc,r.anchor,r.head)}}}):function(t){return it(e,t)||st(t)}),C||et(t.scroller,"contextmenu",function(t){return ma(e,t)});var n,r={end:0};function i(){t.activeTouch&&(n=setTimeout(function(){return t.activeTouch=null},1e3),(r=t.activeTouch).end=+new Date)}function o(e,t){if(null==t.left)return!0;var n=t.left-e.left,r=t.top-e.top;return n*n+r*r>400}et(t.scroller,"touchstart",function(i){if(!it(e,i)&&!function(e){if(1!=e.touches.length)return!1;var t=e.touches[0];return t.radiusX<=1&&t.radiusY<=1}(i)&&!pa(e,i)){t.input.ensurePolled(),clearTimeout(n);var o=+new Date;t.activeTouch={start:o,moved:!1,prev:o-r.end<=300?r:null},1==i.touches.length&&(t.activeTouch.left=i.touches[0].pageX,t.activeTouch.top=i.touches[0].pageY)}}),et(t.scroller,"touchmove",function(){t.activeTouch&&(t.activeTouch.moved=!0)}),et(t.scroller,"touchend",function(n){var r=t.activeTouch;if(r&&!wn(t,n)&&null!=r.left&&!r.moved&&new Date-r.start<300){var a,l=e.coordsChar(t.activeTouch,"page");a=!r.prev||o(r,r.prev)?new yi(l,l):!r.prev.prev||o(r,r.prev.prev)?e.findWordAt(l):new yi(me(l.line,0),ke(e.doc,me(l.line+1,0))),e.setSelection(a.anchor,a.head),e.focus(),st(n)}i()}),et(t.scroller,"touchcancel",i),et(t.scroller,"scroll",function(){t.scroller.clientHeight&&(Or(e,t.scroller.scrollTop),Nr(e,t.scroller.scrollLeft,!0),rt(e,"scroll",e))}),et(t.scroller,"mousewheel",function(t){return gi(e,t)}),et(t.scroller,"DOMMouseScroll",function(t){return gi(e,t)}),et(t.wrapper,"scroll",function(){return t.wrapper.scrollTop=t.wrapper.scrollLeft=0}),t.dragFunctions={enter:function(t){it(e,t)||ft(t)},over:function(t){it(e,t)||(function(e,t){var n=ar(e,t);if(n){var r=document.createDocumentFragment();ur(e,n,r),e.display.dragCursor||(e.display.dragCursor=O("div",null,"CodeMirror-cursors CodeMirror-dragcursors"),e.display.lineSpace.insertBefore(e.display.dragCursor,e.display.cursorDiv)),A(e.display.dragCursor,r)}}(e,t),ft(t))},start:function(t){return function(e,t){if(a&&(!e.state.draggingText||+new Date-To<100))ft(t);else if(!it(e,t)&&!wn(e.display,t)&&(t.dataTransfer.setData("Text",e.getSelection()),t.dataTransfer.effectAllowed="copyMove",t.dataTransfer.setDragImage&&!d)){var n=O("img",null,null,"position: fixed; left: 0; top: 0;");n.src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==",f&&(n.width=n.height=1,e.display.wrapper.appendChild(n),n._top=n.offsetTop),t.dataTransfer.setDragImage(n,0,0),f&&n.parentNode.removeChild(n)}}(e,t)},drop:Gr(e,Ao),leave:function(t){it(e,t)||Oo(e)}};var s=t.input.getField();et(s,"keyup",function(t){return aa.call(e,t)}),et(s,"keydown",Gr(e,oa)),et(s,"keypress",Gr(e,la)),et(s,"focus",function(t){return gr(e,t)}),et(s,"blur",function(t){return vr(e,t)})}(this),Po(),_r(this),this.curOp.forceUpdate=!0,Ei(this,i),t.autofocus&&!v||this.hasFocus()?setTimeout(D(gr,this),20):vr(this),ba)ba.hasOwnProperty(u)&&ba[u](r,t[u],va);kr(this),t.finishInit&&t.finishInit(this);for(var h=0;h150)){if(!r)return;n="prev"}}else c=0,n="not";"prev"==n?c=t>o.first?z(le(o,t-1).text,null,a):0:"add"==n?c=s+e.options.indentUnit:"subtract"==n?c=s-e.options.indentUnit:"number"==typeof n&&(c=s+n),c=Math.max(0,c);var f="",d=0;if(e.options.indentWithTabs)for(var h=Math.floor(c/a);h;--h)d+=a,f+="\t";if(d1)if(Ma&&Ma.text.join("\n")==t){if(r.ranges.length%Ma.text.length==0){c=[];for(var u=0;u=0;f--){var d=r.ranges[f],h=d.from(),p=d.to();d.empty()&&(n&&n>0?h=me(h.line,h.ch-n):e.state.overwrite&&!l?p=me(p.line,Math.min(le(o,p.line).text.length,p.ch+X(s).length)):Ma&&Ma.lineWise&&Ma.text.join("\n")==t&&(h=p=me(h.line,0))),a=e.curOp.updateInput;var m={from:h,to:p,text:c?c[f%c.length]:s,origin:i||(l?"paste":e.state.cutIncoming?"cut":"+input")};io(e.doc,m),ln(e,"inputRead",e,m)}t&&!l&&Ea(e,t),Lr(e),e.curOp.updateInput=a,e.curOp.typing=!0,e.state.pasteIncoming=e.state.cutIncoming=!1}function Oa(e,t){var n=e.clipboardData&&e.clipboardData.getData("Text");if(n)return e.preventDefault(),t.isReadOnly()||t.options.disableInput||$r(t,function(){return Aa(t,n,0,null,"paste")}),!0}function Ea(e,t){if(e.options.electricChars&&e.options.smartIndent)for(var n=e.doc.sel,r=n.ranges.length-1;r>=0;r--){var i=n.ranges[r];if(!(i.head.ch>100||r&&n.ranges[r-1].head.line==i.head.line)){var o=e.getModeAt(i.head),a=!1;if(o.electricChars){for(var l=0;l-1){a=La(e,i.head.line,"smart");break}}else o.electricInput&&o.electricInput.test(le(e.doc,i.head.line).text.slice(0,i.head.ch))&&(a=La(e,i.head.line,"smart"));a&&ln(e,"electricInput",e,i.head.line)}}}function Na(e){for(var t=[],n=[],r=0;r=t.text.length?(n.ch=t.text.length,n.sticky="before"):n.ch<=0&&(n.ch=0,n.sticky="after");var o=Ye(i,n.ch,n.sticky),a=i[o];if("ltr"==e.doc.direction&&a.level%2==0&&(r>0?a.to>n.ch:a.from=a.from&&d>=u.begin)){var h=f?"before":"after";return new me(n.line,d,h)}}var p=function(e,t,r){for(var o=function(e,t){return t?new me(n.line,s(e,1),"before"):new me(n.line,e,"after")};e>=0&&e0==(1!=a.level),c=l?r.begin:s(r.end,-1);if(a.from<=c&&c0?u.end:s(u.begin,-1);return null==g||r>0&&g==t.text.length||!(m=p(r>0?0:i.length-1,r,c(g)))?null:m}(e.cm,l,t,n):Go(l,t,n))){if(r||!function(){var r=t.line+n;return!(r=e.first+e.size)&&(t=new me(r,t.ch,t.sticky),l=le(e,r))}())return!1;t=Xo(i,e.cm,l,t.line,n)}else t=o;return!0}if("char"==r)s();else if("column"==r)s(!0);else if("word"==r||"group"==r)for(var c=null,u="group"==r,f=e.cm&&e.cm.getHelper(t,"wordChars"),d=!0;!(n<0)||s(!d);d=!1){var h=l.text.charAt(t.ch)||"\n",p=te(h,f)?"w":u&&"\n"==h?"n":!u||/\s/.test(h)?null:"p";if(!u||d||p||(p="s"),c&&c!=p){n<0&&(n=1,s(),t.sticky="after");break}if(p&&(c=p),n>0&&!s(!d))break}var m=eo(e,t,o,a,!0);return ve(o,m)&&(m.hitSide=!0),m}function Ba(e,t,n,r){var i,o,a=e.doc,l=t.left;if("page"==r){var s=Math.min(e.display.wrapper.clientHeight,window.innerHeight||document.documentElement.clientHeight),c=Math.max(s-.5*er(e.display),3);i=(n>0?t.bottom:t.top)+n*c}else"line"==r&&(i=n>0?t.bottom+3:t.top-3);for(;(o=Xn(e,l,i)).outside;){if(n<0?i<=0:i>=a.height){o.hitSide=!0;break}i+=5*n}return o}var Da=function(e){this.cm=e,this.lastAnchorNode=this.lastAnchorOffset=this.lastFocusNode=this.lastFocusOffset=null,this.polling=new W,this.composing=null,this.gracePeriod=!1,this.readDOMTimeout=null};function Fa(e,t){var n=En(e,t.line);if(!n||n.hidden)return null;var r=le(e.doc,t.line),i=An(n,r,t.line),o=Je(r,e.doc.direction),a="left";if(o){var l=Ye(o,t.ch);a=l%2?"right":"left"}var s=Bn(i.map,t.ch,a);return s.offset="right"==s.collapse?s.end:s.start,s}function za(e,t){return t&&(e.bad=!0),e}function Wa(e,t,n){var r;if(t==e.display.lineDiv){if(!(r=e.display.lineDiv.childNodes[n]))return za(e.clipPos(me(e.display.viewTo-1)),!0);t=null,n=0}else for(r=t;;r=r.parentNode){if(!r||r==e.display.lineDiv)return null;if(r.parentNode&&r.parentNode==e.display.lineDiv)break}for(var i=0;i=t.display.viewTo||o.line=t.display.viewFrom&&Fa(t,i)||{node:s[0].measure.map[2],offset:0},u=o.liner.firstLine()&&(a=me(a.line-1,le(r.doc,a.line-1).length)),l.ch==le(r.doc,l.line).text.length&&l.linei.viewTo-1)return!1;a.line==i.viewFrom||0==(e=lr(r,a.line))?(t=fe(i.view[0].line),n=i.view[0].node):(t=fe(i.view[e].line),n=i.view[e-1].node.nextSibling);var s,c,u=lr(r,l.line);if(u==i.view.length-1?(s=i.viewTo-1,c=i.lineDiv.lastChild):(s=fe(i.view[u+1].line)-1,c=i.view[u+1].node.previousSibling),!n)return!1;for(var f=r.doc.splitLines(function(e,t,n,r,i){var o="",a=!1,l=e.doc.lineSeparator(),s=!1;function c(){a&&(o+=l,s&&(o+=l),a=s=!1)}function u(e){e&&(c(),o+=e)}function f(t){if(1==t.nodeType){var n=t.getAttribute("cm-text");if(n)return void u(n);var o,d=t.getAttribute("cm-marker");if(d){var h=e.findMarks(me(r,0),me(i+1,0),function(e){return function(t){return t.id==e}}(+d));return void(h.length&&(o=h[0].find(0))&&u(se(e.doc,o.from,o.to).join(l)))}if("false"==t.getAttribute("contenteditable"))return;var p=/^(pre|div|p|li|table|br)$/i.test(t.nodeName);if(!/^br$/i.test(t.nodeName)&&0==t.textContent.length)return;p&&c();for(var m=0;m1&&d.length>1;)if(X(f)==X(d))f.pop(),d.pop(),s--;else{if(f[0]!=d[0])break;f.shift(),d.shift(),t++}for(var h=0,p=0,m=f[0],g=d[0],v=Math.min(m.length,g.length);ha.ch&&y.charCodeAt(y.length-p-1)==b.charCodeAt(b.length-p-1);)h--,p++;f[f.length-1]=y.slice(0,y.length-p).replace(/^\u200b+/,""),f[0]=f[0].slice(h).replace(/\u200b+$/,"");var w=me(t,h),k=me(s,d.length?X(d).length-p:0);return f.length>1||f[0]||ge(w,k)?(co(r.doc,f,w,k,"+input"),!0):void 0},Da.prototype.ensurePolled=function(){this.forceCompositionEnd()},Da.prototype.reset=function(){this.forceCompositionEnd()},Da.prototype.forceCompositionEnd=function(){this.composing&&(clearTimeout(this.readDOMTimeout),this.composing=null,this.updateFromDOM(),this.div.blur(),this.div.focus())},Da.prototype.readFromDOMSoon=function(){var e=this;null==this.readDOMTimeout&&(this.readDOMTimeout=setTimeout(function(){if(e.readDOMTimeout=null,e.composing){if(!e.composing.done)return;e.composing=null}e.updateFromDOM()},80))},Da.prototype.updateFromDOM=function(){var e=this;!this.cm.isReadOnly()&&this.pollContent()||$r(this.cm,function(){return Zr(e.cm)})},Da.prototype.setUneditable=function(e){e.contentEditable="false"},Da.prototype.onKeyPress=function(e){0==e.charCode||this.composing||(e.preventDefault(),this.cm.isReadOnly()||Gr(this.cm,Aa)(this.cm,String.fromCharCode(null==e.charCode?e.keyCode:e.charCode),0))},Da.prototype.readOnlyChanged=function(e){this.div.contentEditable=String("nocursor"!=e)},Da.prototype.onContextMenu=function(){},Da.prototype.resetPosition=function(){},Da.prototype.needsContentAttribute=!0;var Ha=function(e){this.cm=e,this.prevInput="",this.pollingFast=!1,this.polling=new W,this.hasSelection=!1,this.composing=null};Ha.prototype.init=function(e){var t=this,n=this,r=this.cm;this.createField(e);var i=this.textarea;function o(e){if(!it(r,e)){if(r.somethingSelected())Ta({lineWise:!1,text:r.getSelections()});else{if(!r.options.lineWiseCopyCut)return;var t=Na(r);Ta({lineWise:!0,text:t.text}),"cut"==e.type?r.setSelections(t.ranges,null,j):(n.prevInput="",i.value=t.text.join("\n"),B(i))}"cut"==e.type&&(r.state.cutIncoming=!0)}}e.wrapper.insertBefore(this.wrapper,e.wrapper.firstChild),m&&(i.style.width="0px"),et(i,"input",function(){a&&l>=9&&t.hasSelection&&(t.hasSelection=null),n.poll()}),et(i,"paste",function(e){it(r,e)||Oa(e,r)||(r.state.pasteIncoming=!0,n.fastPoll())}),et(i,"cut",o),et(i,"copy",o),et(e.scroller,"paste",function(t){wn(e,t)||it(r,t)||(r.state.pasteIncoming=!0,n.focus())}),et(e.lineSpace,"selectstart",function(t){wn(e,t)||st(t)}),et(i,"compositionstart",function(){var e=r.getCursor("from");n.composing&&n.composing.range.clear(),n.composing={start:e,range:r.markText(e,r.getCursor("to"),{className:"CodeMirror-composing"})}}),et(i,"compositionend",function(){n.composing&&(n.poll(),n.composing.range.clear(),n.composing=null)})},Ha.prototype.createField=function(e){this.wrapper=Ia(),this.textarea=this.wrapper.firstChild},Ha.prototype.prepareSelection=function(){var e=this.cm,t=e.display,n=e.doc,r=cr(e);if(e.options.moveInputWithCursor){var i=qn(e,n.sel.primary().head,"div"),o=t.wrapper.getBoundingClientRect(),a=t.lineDiv.getBoundingClientRect();r.teTop=Math.max(0,Math.min(t.wrapper.clientHeight-10,i.top+a.top-o.top)),r.teLeft=Math.max(0,Math.min(t.wrapper.clientWidth-10,i.left+a.left-o.left))}return r},Ha.prototype.showSelection=function(e){var t=this.cm,n=t.display;A(n.cursorDiv,e.cursors),A(n.selectionDiv,e.selection),null!=e.teTop&&(this.wrapper.style.top=e.teTop+"px",this.wrapper.style.left=e.teLeft+"px")},Ha.prototype.reset=function(e){if(!this.contextMenuPending&&!this.composing){var t=this.cm;if(t.somethingSelected()){this.prevInput="";var n=t.getSelection();this.textarea.value=n,t.state.focused&&B(this.textarea),a&&l>=9&&(this.hasSelection=n)}else e||(this.prevInput=this.textarea.value="",a&&l>=9&&(this.hasSelection=null))}},Ha.prototype.getField=function(){return this.textarea},Ha.prototype.supportsTouch=function(){return!1},Ha.prototype.focus=function(){if("nocursor"!=this.cm.options.readOnly&&(!v||P()!=this.textarea))try{this.textarea.focus()}catch(e){}},Ha.prototype.blur=function(){this.textarea.blur()},Ha.prototype.resetPosition=function(){this.wrapper.style.top=this.wrapper.style.left=0},Ha.prototype.receivedFocus=function(){this.slowPoll()},Ha.prototype.slowPoll=function(){var e=this;this.pollingFast||this.polling.set(this.cm.options.pollInterval,function(){e.poll(),e.cm.state.focused&&e.slowPoll()})},Ha.prototype.fastPoll=function(){var e=!1,t=this;t.pollingFast=!0,t.polling.set(20,function n(){var r=t.poll();r||e?(t.pollingFast=!1,t.slowPoll()):(e=!0,t.polling.set(60,n))})},Ha.prototype.poll=function(){var e=this,t=this.cm,n=this.textarea,r=this.prevInput;if(this.contextMenuPending||!t.state.focused||xt(n)&&!r&&!this.composing||t.isReadOnly()||t.options.disableInput||t.state.keySeq)return!1;var i=n.value;if(i==r&&!t.somethingSelected())return!1;if(a&&l>=9&&this.hasSelection===i||y&&/[\uf700-\uf7ff]/.test(i))return t.display.input.reset(),!1;if(t.doc.sel==t.display.selForContextMenu){var o=i.charCodeAt(0);if(8203!=o||r||(r="​"),8666==o)return this.reset(),this.cm.execCommand("undo")}for(var s=0,c=Math.min(r.length,i.length);s1e3||i.indexOf("\n")>-1?n.value=e.prevInput="":e.prevInput=i,e.composing&&(e.composing.range.clear(),e.composing.range=t.markText(e.composing.start,t.getCursor("to"),{className:"CodeMirror-composing"}))}),!0},Ha.prototype.ensurePolled=function(){this.pollingFast&&this.poll()&&(this.pollingFast=!1)},Ha.prototype.onKeyPress=function(){a&&l>=9&&(this.hasSelection=null),this.fastPoll()},Ha.prototype.onContextMenu=function(e){var t=this,n=t.cm,r=n.display,i=t.textarea,o=ar(n,e),c=r.scroller.scrollTop;if(o&&!f){var u=n.options.resetSelectionOnContextMenu;u&&-1==n.doc.sel.contains(o)&&Gr(n,Gi)(n.doc,xi(o),j);var d=i.style.cssText,h=t.wrapper.style.cssText;t.wrapper.style.cssText="position: absolute";var p,m=t.wrapper.getBoundingClientRect();if(i.style.cssText="position: absolute; width: 30px; height: 30px;\n top: "+(e.clientY-m.top-5)+"px; left: "+(e.clientX-m.left-5)+"px;\n z-index: 1000; background: "+(a?"rgba(255, 255, 255, .05)":"transparent")+";\n outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);",s&&(p=window.scrollY),r.input.focus(),s&&window.scrollTo(null,p),r.input.reset(),n.somethingSelected()||(i.value=t.prevInput=" "),t.contextMenuPending=!0,r.selForContextMenu=n.doc.sel,clearTimeout(r.detectingSelectAll),a&&l>=9&&v(),C){ft(e);var g=function(){nt(window,"mouseup",g),setTimeout(y,20)};et(window,"mouseup",g)}else setTimeout(y,50)}function v(){if(null!=i.selectionStart){var e=n.somethingSelected(),o="​"+(e?i.value:"");i.value="⇚",i.value=o,t.prevInput=e?"":"​",i.selectionStart=1,i.selectionEnd=o.length,r.selForContextMenu=n.doc.sel}}function y(){if(t.contextMenuPending=!1,t.wrapper.style.cssText=h,i.style.cssText=d,a&&l<9&&r.scrollbars.setScrollTop(r.scroller.scrollTop=c),null!=i.selectionStart){(!a||a&&l<9)&&v();var e=0,o=function(){r.selForContextMenu==n.doc.sel&&0==i.selectionStart&&i.selectionEnd>0&&"​"==t.prevInput?Gr(n,no)(n):e++<10?r.detectingSelectAll=setTimeout(o,500):(r.selForContextMenu=null,r.input.reset())};r.detectingSelectAll=setTimeout(o,200)}}},Ha.prototype.readOnlyChanged=function(e){e||this.reset(),this.textarea.disabled="nocursor"==e},Ha.prototype.setUneditable=function(){},Ha.prototype.needsContentAttribute=!1,function(e){var t=e.optionHandlers;function n(n,r,i,o){e.defaults[n]=r,i&&(t[n]=o?function(e,t,n){n!=va&&i(e,t,n)}:i)}e.defineOption=n,e.Init=va,n("value","",function(e,t){return e.setValue(t)},!0),n("mode",null,function(e,t){e.doc.modeOption=t,Li(e)},!0),n("indentUnit",2,Li,!0),n("indentWithTabs",!1),n("smartIndent",!0),n("tabSize",4,function(e){Mi(e),Wn(e),Zr(e)},!0),n("lineSeparator",null,function(e,t){if(e.doc.lineSep=t,t){var n=[],r=e.doc.first;e.doc.iter(function(e){for(var i=0;;){var o=e.text.indexOf(t,i);if(-1==o)break;i=o+t.length,n.push(me(r,o))}r++});for(var i=n.length-1;i>=0;i--)co(e.doc,t,n[i],me(n[i].line,n[i].ch+t.length))}}),n("specialChars",/[\u0000-\u001f\u007f-\u009f\u00ad\u061c\u200b-\u200f\u2028\u2029\ufeff]/g,function(e,t,n){e.state.specialChars=new RegExp(t.source+(t.test("\t")?"":"|\t"),"g"),n!=va&&e.refresh()}),n("specialCharPlaceholder",Zt,function(e){return e.refresh()},!0),n("electricChars",!0),n("inputStyle",v?"contenteditable":"textarea",function(){throw new Error("inputStyle can not (yet) be changed in a running editor")},!0),n("spellcheck",!1,function(e,t){return e.getInputField().spellcheck=t},!0),n("rtlMoveVisually",!x),n("wholeLineUpdateBefore",!0),n("theme","default",function(e){ga(e),xa(e)},!0),n("keyMap","default",function(e,t,n){var r=Vo(t),i=n!=va&&Vo(n);i&&i.detach&&i.detach(e,r),r.attach&&r.attach(e,i||null)}),n("extraKeys",null),n("configureMouse",null),n("lineWrapping",!1,ka,!0),n("gutters",[],function(e){fi(e.options),xa(e)},!0),n("fixedGutter",!0,function(e,t){e.display.gutters.style.left=t?rr(e.display)+"px":"0",e.refresh()},!0),n("coverGutterNextToScrollbar",!1,function(e){return Br(e)},!0),n("scrollbarStyle","native",function(e){zr(e),Br(e),e.display.scrollbars.setScrollTop(e.doc.scrollTop),e.display.scrollbars.setScrollLeft(e.doc.scrollLeft)},!0),n("lineNumbers",!1,function(e){fi(e.options),xa(e)},!0),n("firstLineNumber",1,xa,!0),n("lineNumberFormatter",function(e){return e},xa,!0),n("showCursorWhenSelecting",!1,sr,!0),n("resetSelectionOnContextMenu",!0),n("lineWiseCopyCut",!0),n("pasteLinesPerSelection",!0),n("readOnly",!1,function(e,t){"nocursor"==t&&(vr(e),e.display.input.blur()),e.display.input.readOnlyChanged(t)}),n("disableInput",!1,function(e,t){t||e.display.input.reset()},!0),n("dragDrop",!0,wa),n("allowDropFileTypes",null),n("cursorBlinkRate",530),n("cursorScrollMargin",0),n("cursorHeight",1,sr,!0),n("singleCursorHeightPerLine",!0,sr,!0),n("workTime",100),n("workDelay",100),n("flattenSpans",!0,Mi,!0),n("addModeClass",!1,Mi,!0),n("pollInterval",100),n("undoDepth",200,function(e,t){return e.doc.history.undoDepth=t}),n("historyEventDelay",1250),n("viewportMargin",10,function(e){return e.refresh()},!0),n("maxHighlightLength",1e4,Mi,!0),n("moveInputWithCursor",!0,function(e,t){t||e.display.input.resetPosition()}),n("tabindex",null,function(e,t){return e.display.input.getField().tabIndex=t||""}),n("autofocus",null),n("direction","ltr",function(e,t){return e.doc.setDirection(t)},!0)}(Ca),function(e){var t=e.optionHandlers,n=e.helpers={};e.prototype={constructor:e,focus:function(){window.focus(),this.display.input.focus()},setOption:function(e,n){var r=this.options,i=r[e];r[e]==n&&"mode"!=e||(r[e]=n,t.hasOwnProperty(e)&&Gr(this,t[e])(this,n,i),rt(this,"optionChange",this,e))},getOption:function(e){return this.options[e]},getDoc:function(){return this.doc},addKeyMap:function(e,t){this.state.keyMaps[t?"push":"unshift"](Vo(e))},removeKeyMap:function(e){for(var t=this.state.keyMaps,n=0;nn&&(La(this,i.head.line,e,!0),n=i.head.line,r==this.doc.sel.primIndex&&Lr(this));else{var o=i.from(),a=i.to(),l=Math.max(n,o.line);n=Math.min(this.lastLine(),a.line-(a.ch?0:1))+1;for(var s=l;s0&&Vi(this.doc,r,new yi(o,c[r].to()),j)}}}),getTokenAt:function(e,t){return Kt(this,e,t)},getLineTokens:function(e,t){return Kt(this,me(e),t,!0)},getTokenTypeAt:function(e){e=ke(this.doc,e);var t,n=Dt(this,le(this.doc,e.line)),r=0,i=(n.length-1)/2,o=e.ch;if(0==o)t=n[2];else for(;;){var a=r+i>>1;if((a?n[2*a-1]:0)>=o)i=a;else{if(!(n[2*a+1]o&&(e=o,i=!0),r=le(this.doc,e)}else r=e;return jn(this,r,{top:0,left:0},t||"page",n||i).top+(i?this.doc.height-qe(r):0)},defaultTextHeight:function(){return er(this.display)},defaultCharWidth:function(){return tr(this.display)},getViewport:function(){return{from:this.display.viewFrom,to:this.display.viewTo}},addWidget:function(e,t,n,r,i){var o=this.display,a=(e=qn(this,ke(this.doc,e))).bottom,l=e.left;if(t.style.position="absolute",t.setAttribute("cm-ignore-events","true"),this.display.input.setUneditable(t),o.sizer.appendChild(t),"over"==r)a=e.top;else if("above"==r||"near"==r){var s=Math.max(o.wrapper.clientHeight,this.doc.height),c=Math.max(o.sizer.clientWidth,o.lineSpace.clientWidth);("above"==r||e.bottom+t.offsetHeight>s)&&e.top>t.offsetHeight?a=e.top-t.offsetHeight:e.bottom+t.offsetHeight<=s&&(a=e.bottom),l+t.offsetWidth>c&&(l=c-t.offsetWidth)}t.style.top=a+"px",t.style.left=t.style.right="","right"==i?(l=o.sizer.clientWidth-t.offsetWidth,t.style.right="0px"):("left"==i?l=0:"middle"==i&&(l=(o.sizer.clientWidth-t.offsetWidth)/2),t.style.left=l+"px"),n&&function(e,t){var n=Cr(e,t);null!=n.scrollTop&&Or(e,n.scrollTop),null!=n.scrollLeft&&Nr(e,n.scrollLeft)}(this,{left:l,top:a,right:l+t.offsetWidth,bottom:a+t.offsetHeight})},triggerOnKeyDown:Xr(oa),triggerOnKeyPress:Xr(la),triggerOnKeyUp:aa,triggerOnMouseDown:Xr(fa),execCommand:function(e){if(Yo.hasOwnProperty(e))return Yo[e].call(null,this)},triggerElectric:Xr(function(e){Ea(this,e)}),findPosH:function(e,t,n,r){var i=1;t<0&&(i=-1,t=-t);for(var o=ke(this.doc,e),a=0;a0&&l(n.charAt(r-1));)--r;for(;i.5)&&or(this),rt(this,"refresh",this)}),swapDoc:Xr(function(e){var t=this.doc;return t.cm=null,Ei(this,e),Wn(this),this.display.input.reset(),Mr(this,e.scrollLeft,e.scrollTop),this.curOp.forceScroll=!0,ln(this,"swapDoc",this,t),t}),getInputField:function(){return this.display.input.getField()},getWrapperElement:function(){return this.display.wrapper},getScrollerElement:function(){return this.display.scroller},getGutterElement:function(){return this.display.gutters}},lt(e),e.registerHelper=function(t,r,i){n.hasOwnProperty(t)||(n[t]=e[t]={_global:[]}),n[t][r]=i},e.registerGlobalHelper=function(t,r,i,o){e.registerHelper(t,r,o),n[t]._global.push({pred:i,val:o})}}(Ca);var Ka="iter insert remove copy getEditor constructor".split(" ");for(var ja in Mo.prototype)Mo.prototype.hasOwnProperty(ja)&&_(Ka,ja)<0&&(Ca.prototype[ja]=function(e){return function(){return e.apply(this.doc,arguments)}}(Mo.prototype[ja]));return lt(Mo),Ca.inputStyles={textarea:Ha,contenteditable:Da},Ca.defineMode=function(e){Ca.defaults.mode||"null"==e||(Ca.defaults.mode=e),function(e,t){arguments.length>2&&(t.dependencies=Array.prototype.slice.call(arguments,2)),Ct[e]=t}.apply(this,arguments)},Ca.defineMIME=function(e,t){St[e]=t},Ca.defineMode("null",function(){return{token:function(e){return e.skipToEnd()}}}),Ca.defineMIME("text/plain","null"),Ca.defineExtension=function(e,t){Ca.prototype[e]=t},Ca.defineDocExtension=function(e,t){Mo.prototype[e]=t},Ca.fromTextArea=function(e,t){if((t=t?F(t):{}).value=e.value,!t.tabindex&&e.tabIndex&&(t.tabindex=e.tabIndex),!t.placeholder&&e.placeholder&&(t.placeholder=e.placeholder),null==t.autofocus){var n=P();t.autofocus=n==e||null!=e.getAttribute("autofocus")&&n==document.body}function r(){e.value=l.getValue()}var i;if(e.form&&(et(e.form,"submit",r),!t.leaveSubmitMethodAlone)){var o=e.form;i=o.submit;try{var a=o.submit=function(){r(),o.submit=i,o.submit(),o.submit=a}}catch(e){}}t.finishInit=function(t){t.save=r,t.getTextArea=function(){return e},t.toTextArea=function(){t.toTextArea=isNaN,r(),e.parentNode.removeChild(t.getWrapperElement()),e.style.display="",e.form&&(nt(e.form,"submit",r),"function"==typeof e.form.submit&&(e.form.submit=i))}},e.style.display="none";var l=Ca(function(t){return e.parentNode.insertBefore(t,e.nextSibling)},t);return l},function(e){e.off=nt,e.on=et,e.wheelEventPixels=mi,e.Doc=Mo,e.splitLines=bt,e.countColumn=z,e.findColumn=q,e.isWordChar=ee,e.Pass=K,e.signal=rt,e.Line=Vt,e.changeEnd=wi,e.scrollbarModel=Fr,e.Pos=me,e.cmpPos=ge,e.modes=Ct,e.mimeModes=St,e.resolveMode=Lt,e.getMode=Mt,e.modeExtensions=Tt,e.extendMode=At,e.copyState=Ot,e.startState=Nt,e.innerMode=Et,e.commands=Yo,e.keyMap=zo,e.keyName=Uo,e.isModifierKey=Ko,e.lookupKey=Ho,e.normalizeKeyMap=_o,e.StringStream=Pt,e.SharedTextMarker=ko,e.TextMarker=xo,e.LineWidget=vo,e.e_preventDefault=st,e.e_stopPropagation=ct,e.e_stop=ft,e.addClass=I,e.contains=N,e.rmClass=M,e.keyNames=Ro}(Ca),Ca.version="5.39.0",Ca}()},function(e,t,n){!function(e){"use strict";var t,n,r=e.Pos;function i(e,t){for(var n=function(e){var t=e.flags;return null!=t?t:(e.ignoreCase?"i":"")+(e.global?"g":"")+(e.multiline?"m":"")}(e),r=n,i=0;i>1,l=r(e.slice(0,a)).length;if(l==n)return a;l>n?o=a:i=a+1}}function s(e,s,c,u){var f;this.atOccurrence=!1,this.doc=e,c=c?e.clipPos(c):r(0,0),this.pos={from:c,to:c},"object"==typeof u?f=u.caseFold:(f=u,u=null),"string"==typeof s?(null==f&&(f=!1),this.matches=function(i,o){return(i?function(e,i,o,a){if(!i.length)return null;var s=a?t:n,c=s(i).split(/\r|\n\r?/);e:for(var u=o.line,f=o.ch,d=e.firstLine()-1+c.length;u>=d;u--,f=-1){var h=e.getLine(u);f>-1&&(h=h.slice(0,f));var p=s(h);if(1==c.length){var m=p.lastIndexOf(c[0]);if(-1==m)continue e;return{from:r(u,l(h,p,m,s)),to:r(u,l(h,p,m+c[0].length,s))}}var g=c[c.length-1];if(p.slice(0,g.length)==g){for(var v=1,o=u-c.length+1;v=s;o--,l=-1){var c=e.getLine(o);l>-1&&(c=c.slice(0,l));var u=a(c,t);if(u)return{from:r(o,u.index),to:r(o,u.index+u[0].length),match:u}}}:o)(e,s,n)}:this.matches=function(t,n){return(t?function(e,t,n){t=i(t,"gm");for(var o,l=1,s=n.line,c=e.firstLine();s>=c;){for(var u=0;uc);u++){var f=e.getLine(s++);a=null==a?f:a+"\n"+f}l*=2,t.lastIndex=n.ch;var d=t.exec(a);if(d){var h=a.slice(0,d.index).split("\n"),p=d[0].split("\n"),m=n.line+h.length-1,g=h[h.length-1].length;return{from:r(m,g),to:r(m+p.length-1,1==p.length?g+p[0].length:p[p.length-1].length),match:d}}}})(e,s,n)})}String.prototype.normalize?(t=function(e){return e.normalize("NFD").toLowerCase()},n=function(e){return e.normalize("NFD")}):(t=function(e){return e.toLowerCase()},n=function(e){return e}),s.prototype={findNext:function(){return this.find(!1)},findPrevious:function(){return this.find(!0)},find:function(t){for(var n=this.matches(t,this.doc.clipPos(t?this.pos.from:this.pos.to));n&&0==e.cmpPos(n.from,n.to);)t?n.from.ch?n.from=r(n.from.line,n.from.ch-1):n=n.from.line==this.doc.firstLine()?null:this.matches(t,this.doc.clipPos(r(n.from.line-1))):n.to.ch0);)r.push({anchor:i.from(),head:i.to()});r.length&&this.setSelections(r,0)})}(n(0))},function(e,t,n){!function(e){"use strict";var t={autoSelfClosers:{area:!0,base:!0,br:!0,col:!0,command:!0,embed:!0,frame:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0,menuitem:!0},implicitlyClosed:{dd:!0,li:!0,optgroup:!0,option:!0,p:!0,rp:!0,rt:!0,tbody:!0,td:!0,tfoot:!0,th:!0,tr:!0},contextGrabbers:{dd:{dd:!0,dt:!0},dt:{dd:!0,dt:!0},li:{li:!0},option:{option:!0,optgroup:!0},optgroup:{optgroup:!0},p:{address:!0,article:!0,aside:!0,blockquote:!0,dir:!0,div:!0,dl:!0,fieldset:!0,footer:!0,form:!0,h1:!0,h2:!0,h3:!0,h4:!0,h5:!0,h6:!0,header:!0,hgroup:!0,hr:!0,menu:!0,nav:!0,ol:!0,p:!0,pre:!0,section:!0,table:!0,ul:!0},rp:{rp:!0,rt:!0},rt:{rp:!0,rt:!0},tbody:{tbody:!0,tfoot:!0},td:{td:!0,th:!0},tfoot:{tbody:!0},th:{td:!0,th:!0},thead:{tbody:!0,tfoot:!0},tr:{tr:!0}},doNotIndent:{pre:!0},allowUnquoted:!0,allowMissing:!0,caseFold:!0},n={autoSelfClosers:{},implicitlyClosed:{},contextGrabbers:{},doNotIndent:{},allowUnquoted:!1,allowMissing:!1,allowMissingTagName:!1,caseFold:!1};e.defineMode("xml",function(r,i){var o,a,l=r.indentUnit,s={},c=i.htmlMode?t:n;for(var u in c)s[u]=c[u];for(var u in i)s[u]=i[u];function f(e,t){function n(n){return t.tokenize=n,n(e,t)}var r=e.next();return"<"==r?e.eat("!")?e.eat("[")?e.match("CDATA[")?n(h("atom","]]>")):null:e.match("--")?n(h("comment","--\x3e")):e.match("DOCTYPE",!0,!0)?(e.eatWhile(/[\w\._\-]/),n(function e(t){return function(n,r){for(var i;null!=(i=n.next());){if("<"==i)return r.tokenize=e(t+1),r.tokenize(n,r);if(">"==i){if(1==t){r.tokenize=f;break}return r.tokenize=e(t-1),r.tokenize(n,r)}}return"meta"}}(1))):null:e.eat("?")?(e.eatWhile(/[\w\._\-]/),t.tokenize=h("meta","?>"),"meta"):(o=e.eat("/")?"closeTag":"openTag",t.tokenize=d,"tag bracket"):"&"==r?(e.eat("#")?e.eat("x")?e.eatWhile(/[a-fA-F\d]/)&&e.eat(";"):e.eatWhile(/[\d]/)&&e.eat(";"):e.eatWhile(/[\w\.\-:]/)&&e.eat(";"))?"atom":"error":(e.eatWhile(/[^&<]/),null)}function d(e,t){var n=e.next();if(">"==n||"/"==n&&e.eat(">"))return t.tokenize=f,o=">"==n?"endTag":"selfcloseTag","tag bracket";if("="==n)return o="equals",null;if("<"==n){t.tokenize=f,t.state=g,t.tagName=t.tagStart=null;var r=t.tokenize(e,t);return r?r+" tag error":"tag error"}return/[\'\"]/.test(n)?(t.tokenize=function(e){var t=function(t,n){for(;!t.eol();)if(t.next()==e){n.tokenize=d;break}return"string"};return t.isInAttribute=!0,t}(n),t.stringStartCol=e.column(),t.tokenize(e,t)):(e.match(/^[^\s\u00a0=<>\"\']*[^\s\u00a0=<>\"\'\/]/),"word")}function h(e,t){return function(n,r){for(;!n.eol();){if(n.match(t)){r.tokenize=f;break}n.next()}return e}}function p(e){e.context&&(e.context=e.context.prev)}function m(e,t){for(var n;;){if(!e.context)return;if(n=e.context.tagName,!s.contextGrabbers.hasOwnProperty(n)||!s.contextGrabbers[n].hasOwnProperty(t))return;p(e)}}function g(e,t,n){return"openTag"==e?(n.tagStart=t.column(),v):"closeTag"==e?y:g}function v(e,t,n){return"word"==e?(n.tagName=t.current(),a="tag",w):s.allowMissingTagName&&"endTag"==e?(a="tag bracket",w(e,0,n)):(a="error",v)}function y(e,t,n){if("word"==e){var r=t.current();return n.context&&n.context.tagName!=r&&s.implicitlyClosed.hasOwnProperty(n.context.tagName)&&p(n),n.context&&n.context.tagName==r||!1===s.matchClosing?(a="tag",b):(a="tag error",x)}return s.allowMissingTagName&&"endTag"==e?(a="tag bracket",b(e,0,n)):(a="error",x)}function b(e,t,n){return"endTag"!=e?(a="error",b):(p(n),g)}function x(e,t,n){return a="error",b(e,0,n)}function w(e,t,n){if("word"==e)return a="attribute",k;if("endTag"==e||"selfcloseTag"==e){var r=n.tagName,i=n.tagStart;return n.tagName=n.tagStart=null,"selfcloseTag"==e||s.autoSelfClosers.hasOwnProperty(r)?m(n,r):(m(n,r),n.context=new function(e,t,n){this.prev=e.context,this.tagName=t,this.indent=e.indented,this.startOfLine=n,(s.doNotIndent.hasOwnProperty(t)||e.context&&e.context.noIndent)&&(this.noIndent=!0)}(n,r,i==n.indented)),g}return a="error",w}function k(e,t,n){return"equals"==e?C:(s.allowMissing||(a="error"),w(e,0,n))}function C(e,t,n){return"string"==e?S:"word"==e&&s.allowUnquoted?(a="string",w):(a="error",w(e,0,n))}function S(e,t,n){return"string"==e?S:w(e,0,n)}return f.isInText=!0,{startState:function(e){var t={tokenize:f,state:g,indented:e||0,tagName:null,tagStart:null,context:null};return null!=e&&(t.baseIndent=e),t},token:function(e,t){if(!t.tagName&&e.sol()&&(t.indented=e.indentation()),e.eatSpace())return null;o=null;var n=t.tokenize(e,t);return(n||o)&&"comment"!=n&&(a=null,t.state=t.state(o||n,e,t),a&&(n="error"==a?n+" error":a)),n},indent:function(t,n,r){var i=t.context;if(t.tokenize.isInAttribute)return t.tagStart==t.indented?t.stringStartCol+1:t.indented+l;if(i&&i.noIndent)return e.Pass;if(t.tokenize!=d&&t.tokenize!=f)return r?r.match(/^(\s*)/)[0].length:0;if(t.tagName)return!1!==s.multilineTagIndentPastTag?t.tagStart+t.tagName.length+2:t.tagStart+l*(s.multilineTagIndentFactor||1);if(s.alignCDATA&&/$/,blockCommentStart:"\x3c!--",blockCommentEnd:"--\x3e",configuration:s.htmlMode?"html":"xml",helperType:s.htmlMode?"html":"xml",skipAttribute:function(e){e.state==C&&(e.state=w)}}}),e.defineMIME("text/xml","xml"),e.defineMIME("application/xml","xml"),e.mimeModes.hasOwnProperty("text/html")||e.defineMIME("text/html",{name:"xml",htmlMode:!0})}(n(0))},function(e,t,n){!function(e){"use strict";e.defineMode("javascript",function(t,n){var r,i,o=t.indentUnit,a=n.statementIndent,l=n.jsonld,s=n.json||l,c=n.typescript,u=n.wordCharacters||/[\w$\xa1-\uffff]/,f=function(){function e(e){return{type:e,style:"keyword"}}var t=e("keyword a"),n=e("keyword b"),r=e("keyword c"),i=e("keyword d"),o=e("operator"),a={type:"atom",style:"atom"};return{if:e("if"),while:t,with:t,else:n,do:n,try:n,finally:n,return:i,break:i,continue:i,new:e("new"),delete:r,void:r,throw:r,debugger:e("debugger"),var:e("var"),const:e("var"),let:e("var"),function:e("function"),catch:e("catch"),for:e("for"),switch:e("switch"),case:e("case"),default:e("default"),in:o,typeof:o,instanceof:o,true:a,false:a,null:a,undefined:a,NaN:a,Infinity:a,this:e("this"),class:e("class"),super:e("atom"),yield:r,export:e("export"),import:e("import"),extends:r,await:r}}(),d=/[+\-*&%=<>!?|~^@]/,h=/^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/;function p(e,t,n){return r=e,i=n,t}function m(e,t){var n=e.next();if('"'==n||"'"==n)return t.tokenize=function(e){return function(t,n){var r,i=!1;if(l&&"@"==t.peek()&&t.match(h))return n.tokenize=m,p("jsonld-keyword","meta");for(;null!=(r=t.next())&&(r!=e||i);)i=!i&&"\\"==r;return i||(n.tokenize=m),p("string","string")}}(n),t.tokenize(e,t);if("."==n&&e.match(/^\d+(?:[eE][+\-]?\d+)?/))return p("number","number");if("."==n&&e.match(".."))return p("spread","meta");if(/[\[\]{}\(\),;\:\.]/.test(n))return p(n);if("="==n&&e.eat(">"))return p("=>","operator");if("0"==n&&e.match(/^(?:x[\da-f]+|o[0-7]+|b[01]+)n?/i))return p("number","number");if(/\d/.test(n))return e.match(/^\d*(?:n|(?:\.\d*)?(?:[eE][+\-]?\d+)?)?/),p("number","number");if("/"==n)return e.eat("*")?(t.tokenize=g,g(e,t)):e.eat("/")?(e.skipToEnd(),p("comment","comment")):qe(e,t,1)?(function(e){for(var t,n=!1,r=!1;null!=(t=e.next());){if(!n){if("/"==t&&!r)return;"["==t?r=!0:r&&"]"==t&&(r=!1)}n=!n&&"\\"==t}}(e),e.match(/^\b(([gimyus])(?![gimyus]*\2))+\b/),p("regexp","string-2")):(e.eat("="),p("operator","operator",e.current()));if("`"==n)return t.tokenize=v,v(e,t);if("#"==n)return e.skipToEnd(),p("error","error");if(d.test(n))return">"==n&&t.lexical&&">"==t.lexical.type||(e.eat("=")?"!"!=n&&"="!=n||e.eat("="):/[<>*+\-]/.test(n)&&(e.eat(n),">"==n&&e.eat(n))),p("operator","operator",e.current());if(u.test(n)){e.eatWhile(u);var r=e.current();if("."!=t.lastType){if(f.propertyIsEnumerable(r)){var i=f[r];return p(i.type,i.style,r)}if("async"==r&&e.match(/^(\s|\/\*.*?\*\/)*[\[\(\w]/,!1))return p("async","keyword",r)}return p("variable","variable",r)}}function g(e,t){for(var n,r=!1;n=e.next();){if("/"==n&&r){t.tokenize=m;break}r="*"==n}return p("comment","comment")}function v(e,t){for(var n,r=!1;null!=(n=e.next());){if(!r&&("`"==n||"$"==n&&e.eat("{"))){t.tokenize=m;break}r=!r&&"\\"==n}return p("quasi","string-2",e.current())}var y="([{}])";function b(e,t){t.fatArrowAt&&(t.fatArrowAt=null);var n=e.string.indexOf("=>",e.start);if(!(n<0)){if(c){var r=/:\s*(?:\w+(?:<[^>]*>|\[\])?|\{[^}]*\})\s*$/.exec(e.string.slice(e.start,n));r&&(n=r.index)}for(var i=0,o=!1,a=n-1;a>=0;--a){var l=e.string.charAt(a),s=y.indexOf(l);if(s>=0&&s<3){if(!i){++a;break}if(0==--i){"("==l&&(o=!0);break}}else if(s>=3&&s<6)++i;else if(u.test(l))o=!0;else{if(/["'\/]/.test(l))return;if(o&&!i){++a;break}}}o&&!i&&(t.fatArrowAt=a)}}var x={atom:!0,number:!0,variable:!0,string:!0,regexp:!0,this:!0,"jsonld-keyword":!0};function w(e,t,n,r,i,o){this.indented=e,this.column=t,this.type=n,this.prev=i,this.info=o,null!=r&&(this.align=r)}function k(e,t){for(var n=e.localVars;n;n=n.next)if(n.name==t)return!0;for(var r=e.context;r;r=r.prev)for(var n=r.vars;n;n=n.next)if(n.name==t)return!0}var C={state:null,column:null,marked:null,cc:null};function S(){for(var e=arguments.length-1;e>=0;e--)C.cc.push(arguments[e])}function L(){return S.apply(null,arguments),!0}function M(e,t){for(var n=t;n;n=n.next)if(n.name==e)return!0;return!1}function T(e){var t=C.state;if(C.marked="def",t.context)if("var"==t.lexical.info&&t.context&&t.context.block){var r=function e(t,n){if(n){if(n.block){var r=e(t,n.prev);return r?r==n.prev?n:new O(r,n.vars,!0):null}return M(t,n.vars)?n:new O(n.prev,new E(t,n.vars),!1)}return null}(e,t.context);if(null!=r)return void(t.context=r)}else if(!M(e,t.localVars))return void(t.localVars=new E(e,t.localVars));n.globalVars&&!M(e,t.globalVars)&&(t.globalVars=new E(e,t.globalVars))}function A(e){return"public"==e||"private"==e||"protected"==e||"abstract"==e||"readonly"==e}function O(e,t,n){this.prev=e,this.vars=t,this.block=n}function E(e,t){this.name=e,this.next=t}var N=new E("this",new E("arguments",null));function P(){C.state.context=new O(C.state.context,C.state.localVars,!1),C.state.localVars=N}function I(){C.state.context=new O(C.state.context,C.state.localVars,!0),C.state.localVars=null}function R(){C.state.localVars=C.state.context.vars,C.state.context=C.state.context.prev}function B(e,t){var n=function(){var n=C.state,r=n.indented;if("stat"==n.lexical.type)r=n.lexical.indented;else for(var i=n.lexical;i&&")"==i.type&&i.align;i=i.prev)r=i.indented;n.lexical=new w(r,C.stream.column(),e,null,n.lexical,t)};return n.lex=!0,n}function D(){var e=C.state;e.lexical.prev&&(")"==e.lexical.type&&(e.indented=e.lexical.indented),e.lexical=e.lexical.prev)}function F(e){return function t(n){return n==e?L():";"==e||"}"==n||")"==n||"]"==n?S():L(t)}}function z(e,t){return"var"==e?L(B("vardef",t),ye,F(";"),D):"keyword a"==e?L(B("form"),K,z,D):"keyword b"==e?L(B("form"),z,D):"keyword d"==e?C.stream.match(/^\s*$/,!1)?L():L(B("stat"),U,F(";"),D):"debugger"==e?L(F(";")):"{"==e?L(B("}"),I,ae,D,R):";"==e?L():"if"==e?("else"==C.state.lexical.info&&C.state.cc[C.state.cc.length-1]==D&&C.state.cc.pop()(),L(B("form"),K,z,D,Ce)):"function"==e?L(Oe):"for"==e?L(B("form"),Se,z,D):"class"==e||c&&"interface"==t?(C.marked="keyword",L(B("form"),Pe,D)):"variable"==e?c&&"declare"==t?(C.marked="keyword",L(z)):c&&("module"==t||"enum"==t||"type"==t)&&C.stream.match(/^\s*\w/,!1)?(C.marked="keyword","enum"==t?L(Ue):"type"==t?L(ue,F("operator"),ue,F(";")):L(B("form"),be,F("{"),B("}"),ae,D,D)):c&&"namespace"==t?(C.marked="keyword",L(B("form"),_,ae,D)):c&&"abstract"==t?(C.marked="keyword",L(z)):L(B("stat"),Q):"switch"==e?L(B("form"),K,F("{"),B("}","switch"),I,ae,D,D,R):"case"==e?L(_,F(":")):"default"==e?L(F(":")):"catch"==e?L(B("form"),P,W,z,D,R):"export"==e?L(B("stat"),De,D):"import"==e?L(B("stat"),ze,D):"async"==e?L(z):"@"==t?L(_,z):S(B("stat"),_,F(";"),D)}function W(e){if("("==e)return L(Ee,F(")"))}function _(e,t){return j(e,t,!1)}function H(e,t){return j(e,t,!0)}function K(e){return"("!=e?S():L(B(")"),_,F(")"),D)}function j(e,t,n){if(C.state.fatArrowAt==C.stream.start){var r=n?Y:X;if("("==e)return L(P,B(")"),ie(Ee,")"),D,F("=>"),r,R);if("variable"==e)return S(P,be,F("=>"),r,R)}var i=n?q:V;return x.hasOwnProperty(e)?L(i):"function"==e?L(Oe,i):"class"==e||c&&"interface"==t?(C.marked="keyword",L(B("form"),Ne,D)):"keyword c"==e||"async"==e?L(n?H:_):"("==e?L(B(")"),U,F(")"),D,i):"operator"==e||"spread"==e?L(n?H:_):"["==e?L(B("]"),je,D,i):"{"==e?oe(te,"}",null,i):"quasi"==e?S($,i):"new"==e?L(function(e){return function(t){return"."==t?L(e?J:Z):"variable"==t&&c?L(me,e?q:V):S(e?H:_)}}(n)):"import"==e?L(_):L()}function U(e){return e.match(/[;\}\)\],]/)?S():S(_)}function V(e,t){return","==e?L(_):q(e,t,!1)}function q(e,t,n){var r=0==n?V:q,i=0==n?_:H;return"=>"==e?L(P,n?Y:X,R):"operator"==e?/\+\+|--/.test(t)||c&&"!"==t?L(r):c&&"<"==t&&C.stream.match(/^([^>]|<.*?>)*>\s*\(/,!1)?L(B(">"),ie(ue,">"),D,r):"?"==t?L(_,F(":"),i):L(i):"quasi"==e?S($,r):";"!=e?"("==e?oe(H,")","call",r):"."==e?L(ee,r):"["==e?L(B("]"),U,F("]"),D,r):c&&"as"==t?(C.marked="keyword",L(ue,r)):"regexp"==e?(C.state.lastType=C.marked="operator",C.stream.backUp(C.stream.pos-C.stream.start-1),L(i)):void 0:void 0}function $(e,t){return"quasi"!=e?S():"${"!=t.slice(t.length-2)?L($):L(_,G)}function G(e){if("}"==e)return C.marked="string-2",C.state.tokenize=v,L($)}function X(e){return b(C.stream,C.state),S("{"==e?z:_)}function Y(e){return b(C.stream,C.state),S("{"==e?z:H)}function Z(e,t){if("target"==t)return C.marked="keyword",L(V)}function J(e,t){if("target"==t)return C.marked="keyword",L(q)}function Q(e){return":"==e?L(D,z):S(V,F(";"),D)}function ee(e){if("variable"==e)return C.marked="property",L()}function te(e,t){if("async"==e)return C.marked="property",L(te);if("variable"==e||"keyword"==C.style){return C.marked="property","get"==t||"set"==t?L(ne):(c&&C.state.fatArrowAt==C.stream.start&&(n=C.stream.match(/^\s*:\s*/,!1))&&(C.state.fatArrowAt=C.stream.pos+n[0].length),L(re));var n}else{if("number"==e||"string"==e)return C.marked=l?"property":C.style+" property",L(re);if("jsonld-keyword"==e)return L(re);if(c&&A(t))return C.marked="keyword",L(te);if("["==e)return L(_,le,F("]"),re);if("spread"==e)return L(H,re);if("*"==t)return C.marked="keyword",L(te);if(":"==e)return S(re)}}function ne(e){return"variable"!=e?S(re):(C.marked="property",L(Oe))}function re(e){return":"==e?L(H):"("==e?S(Oe):void 0}function ie(e,t,n){function r(i,o){if(n?n.indexOf(i)>-1:","==i){var a=C.state.lexical;return"call"==a.info&&(a.pos=(a.pos||0)+1),L(function(n,r){return n==t||r==t?S():S(e)},r)}return i==t||o==t?L():L(F(t))}return function(n,i){return n==t||i==t?L():S(e,r)}}function oe(e,t,n){for(var r=3;r"),ue):void 0}function fe(e){if("=>"==e)return L(ue)}function de(e,t){return"variable"==e||"keyword"==C.style?(C.marked="property",L(de)):"?"==t?L(de):":"==e?L(ue):"["==e?L(_,le,F("]"),de):void 0}function he(e,t){return"variable"==e&&C.stream.match(/^\s*[?:]/,!1)||"?"==t?L(he):":"==e?L(ue):S(ue)}function pe(e,t){return"<"==t?L(B(">"),ie(ue,">"),D,pe):"|"==t||"."==e||"&"==t?L(ue):"["==e?L(F("]"),pe):"extends"==t||"implements"==t?(C.marked="keyword",L(ue)):void 0}function me(e,t){if("<"==t)return L(B(">"),ie(ue,">"),D,pe)}function ge(){return S(ue,ve)}function ve(e,t){if("="==t)return L(ue)}function ye(e,t){return"enum"==t?(C.marked="keyword",L(Ue)):S(be,le,we,ke)}function be(e,t){return c&&A(t)?(C.marked="keyword",L(be)):"variable"==e?(T(t),L()):"spread"==e?L(be):"["==e?oe(be,"]"):"{"==e?oe(xe,"}"):void 0}function xe(e,t){return"variable"!=e||C.stream.match(/^\s*:/,!1)?("variable"==e&&(C.marked="property"),"spread"==e?L(be):"}"==e?S():L(F(":"),be,we)):(T(t),L(we))}function we(e,t){if("="==t)return L(H)}function ke(e){if(","==e)return L(ye)}function Ce(e,t){if("keyword b"==e&&"else"==t)return L(B("form","else"),z,D)}function Se(e,t){return"await"==t?L(Se):"("==e?L(B(")"),Le,F(")"),D):void 0}function Le(e){return"var"==e?L(ye,F(";"),Te):";"==e?L(Te):"variable"==e?L(Me):S(_,F(";"),Te)}function Me(e,t){return"in"==t||"of"==t?(C.marked="keyword",L(_)):L(V,Te)}function Te(e,t){return";"==e?L(Ae):"in"==t||"of"==t?(C.marked="keyword",L(_)):S(_,F(";"),Ae)}function Ae(e){")"!=e&&L(_)}function Oe(e,t){return"*"==t?(C.marked="keyword",L(Oe)):"variable"==e?(T(t),L(Oe)):"("==e?L(P,B(")"),ie(Ee,")"),D,se,z,R):c&&"<"==t?L(B(">"),ie(ge,">"),D,Oe):void 0}function Ee(e,t){return"@"==t&&L(_,Ee),"spread"==e?L(Ee):c&&A(t)?(C.marked="keyword",L(Ee)):S(be,le,we)}function Ne(e,t){return"variable"==e?Pe(e,t):Ie(e,t)}function Pe(e,t){if("variable"==e)return T(t),L(Ie)}function Ie(e,t){return"<"==t?L(B(">"),ie(ge,">"),D,Ie):"extends"==t||"implements"==t||c&&","==e?("implements"==t&&(C.marked="keyword"),L(c?ue:_,Ie)):"{"==e?L(B("}"),Re,D):void 0}function Re(e,t){return"async"==e||"variable"==e&&("static"==t||"get"==t||"set"==t||c&&A(t))&&C.stream.match(/^\s+[\w$\xa1-\uffff]/,!1)?(C.marked="keyword",L(Re)):"variable"==e||"keyword"==C.style?(C.marked="property",L(c?Be:Oe,Re)):"["==e?L(_,le,F("]"),c?Be:Oe,Re):"*"==t?(C.marked="keyword",L(Re)):";"==e?L(Re):"}"==e?L():"@"==t?L(_,Re):void 0}function Be(e,t){return"?"==t?L(Be):":"==e?L(ue,we):"="==t?L(H):S(Oe)}function De(e,t){return"*"==t?(C.marked="keyword",L(Ke,F(";"))):"default"==t?(C.marked="keyword",L(_,F(";"))):"{"==e?L(ie(Fe,"}"),Ke,F(";")):S(z)}function Fe(e,t){return"as"==t?(C.marked="keyword",L(F("variable"))):"variable"==e?S(H,Fe):void 0}function ze(e){return"string"==e?L():"("==e?S(_):S(We,_e,Ke)}function We(e,t){return"{"==e?oe(We,"}"):("variable"==e&&T(t),"*"==t&&(C.marked="keyword"),L(He))}function _e(e){if(","==e)return L(We,_e)}function He(e,t){if("as"==t)return C.marked="keyword",L(We)}function Ke(e,t){if("from"==t)return C.marked="keyword",L(_)}function je(e){return"]"==e?L():S(ie(H,"]"))}function Ue(){return S(B("form"),be,F("{"),B("}"),ie(Ve,"}"),D,D)}function Ve(){return S(be,we)}function qe(e,t,n){return t.tokenize==m&&/^(?:operator|sof|keyword [bcd]|case|new|export|default|spread|[\[{}\(,;:]|=>)$/.test(t.lastType)||"quasi"==t.lastType&&/\{\s*$/.test(e.string.slice(0,e.pos-(n||0)))}return R.lex=!0,D.lex=!0,{startState:function(e){var t={tokenize:m,lastType:"sof",cc:[],lexical:new w((e||0)-o,0,"block",!1),localVars:n.localVars,context:n.localVars&&new O(null,null,!1),indented:e||0};return n.globalVars&&"object"==typeof n.globalVars&&(t.globalVars=n.globalVars),t},token:function(e,t){if(e.sol()&&(t.lexical.hasOwnProperty("align")||(t.lexical.align=!1),t.indented=e.indentation(),b(e,t)),t.tokenize!=g&&e.eatSpace())return null;var n=t.tokenize(e,t);return"comment"==r?n:(t.lastType="operator"!=r||"++"!=i&&"--"!=i?r:"incdec",function(e,t,n,r,i){var o=e.cc;for(C.state=e,C.stream=i,C.marked=null,C.cc=o,C.style=t,e.lexical.hasOwnProperty("align")||(e.lexical.align=!0);;){var a=o.length?o.pop():s?_:z;if(a(n,r)){for(;o.length&&o[o.length-1].lex;)o.pop()();return C.marked?C.marked:"variable"==n&&k(e,r)?"variable-2":t}}}(t,n,r,i,e))},indent:function(t,r){if(t.tokenize==g)return e.Pass;if(t.tokenize!=m)return 0;var i,l=r&&r.charAt(0),s=t.lexical;if(!/^\s*else\b/.test(r))for(var c=t.cc.length-1;c>=0;--c){var u=t.cc[c];if(u==D)s=s.prev;else if(u!=Ce)break}for(;("stat"==s.type||"form"==s.type)&&("}"==l||(i=t.cc[t.cc.length-1])&&(i==V||i==q)&&!/^[,\.=+\-*:?[\(]/.test(r));)s=s.prev;a&&")"==s.type&&"stat"==s.prev.type&&(s=s.prev);var f=s.type,h=l==f;return"vardef"==f?s.indented+("operator"==t.lastType||","==t.lastType?s.info.length+1:0):"form"==f&&"{"==l?s.indented:"form"==f?s.indented+o:"stat"==f?s.indented+(function(e,t){return"operator"==e.lastType||","==e.lastType||d.test(t.charAt(0))||/[,.]/.test(t.charAt(0))}(t,r)?a||o:0):"switch"!=s.info||h||0==n.doubleIndentSwitch?s.align?s.column+(h?0:1):s.indented+(h?0:o):s.indented+(/^(?:case|default)\b/.test(r)?o:2*o)},electricInput:/^\s*(?:case .*?:|default:|\{|\})$/,blockCommentStart:s?null:"/*",blockCommentEnd:s?null:"*/",blockCommentContinue:s?null:" * ",lineComment:s?null:"//",fold:"brace",closeBrackets:"()[]{}''\"\"``",helperType:s?"json":"javascript",jsonldMode:l,jsonMode:s,expressionAllowed:qe,skipExpression:function(e){var t=e.cc[e.cc.length-1];t!=_&&t!=H||e.cc.pop()}}}),e.registerHelper("wordChars","javascript",/[\w$]/),e.defineMIME("text/javascript","javascript"),e.defineMIME("text/ecmascript","javascript"),e.defineMIME("application/javascript","javascript"),e.defineMIME("application/x-javascript","javascript"),e.defineMIME("application/ecmascript","javascript"),e.defineMIME("application/json",{name:"javascript",json:!0}),e.defineMIME("application/x-json",{name:"javascript",json:!0}),e.defineMIME("application/ld+json",{name:"javascript",jsonld:!0}),e.defineMIME("text/typescript",{name:"javascript",typescript:!0}),e.defineMIME("application/typescript",{name:"javascript",typescript:!0})}(n(0))},function(e,t,n){!function(e){var t=/MSIE \d/.test(navigator.userAgent)&&(null==document.documentMode||document.documentMode<8),n=e.Pos,r={"(":")>",")":"(<","[":"]>","]":"[<","{":"}>","}":"{<"};function i(e,t,i){var a=e.getLineHandle(t.line),l=t.ch-1,s=i&&i.afterCursor;null==s&&(s=/(^| )cm-fat-cursor($| )/.test(e.getWrapperElement().className));var c=!s&&l>=0&&r[a.text.charAt(l)]||r[a.text.charAt(++l)];if(!c)return null;var u=">"==c.charAt(1)?1:-1;if(i&&i.strict&&u>0!=(l==t.ch))return null;var f=e.getTokenTypeAt(n(t.line,l+1)),d=o(e,n(t.line,l+(u>0?1:0)),u,f||null,i);return null==d?null:{from:n(t.line,l),to:d&&d.pos,match:d&&d.ch==c.charAt(0),forward:u>0}}function o(e,t,i,o,a){for(var l=a&&a.maxScanLineLength||1e4,s=a&&a.maxScanLines||1e3,c=[],u=a&&a.bracketRegex?a.bracketRegex:/[(){}[\]]/,f=i>0?Math.min(t.line+s,e.lastLine()+1):Math.max(e.firstLine()-1,t.line-s),d=t.line;d!=f;d+=i){var h=e.getLine(d);if(h){var p=i>0?0:h.length-1,m=i>0?h.length:-1;if(!(h.length>l))for(d==t.line&&(p=t.ch-(i<0?1:0));p!=m;p+=i){var g=h.charAt(p);if(u.test(g)&&(void 0===o||e.getTokenTypeAt(n(d,p+1))==o)){var v=r[g];if(">"==v.charAt(1)==i>0)c.push(g);else{if(!c.length)return{pos:n(d,p),ch:g};c.pop()}}}}}return d-i!=(i>0?e.lastLine():e.firstLine())&&null}function a(e,r,o){for(var a=e.state.matchBrackets.maxHighlightLineLength||1e3,l=[],s=e.listSelections(),c=0;ct.firstLine();)n=e.Pos(n.line-1,0),c=s(!1);if(c&&!c.cleared&&"unfold"!==o){var u=function(e,t){var n=r(e,t,"widget");if("string"==typeof n){var i=document.createTextNode(n);(n=document.createElement("span")).appendChild(i),n.className="CodeMirror-foldmarker"}else n&&(n=n.cloneNode(!0));return n}(t,i);e.on(u,"mousedown",function(t){f.clear(),e.e_preventDefault(t)});var f=t.markText(c.from,c.to,{replacedWith:u,clearOnEnter:r(t,i,"clearOnEnter"),__isFold:!0});f.on("clear",function(n,r){e.signal(t,"unfold",t,n,r)}),e.signal(t,"fold",t,c.from,c.to)}}e.newFoldFunction=function(e,n){return function(r,i){t(r,i,{rangeFinder:e,widget:n})}},e.defineExtension("foldCode",function(e,n,r){t(this,e,n,r)}),e.defineExtension("isFolded",function(e){for(var t=this.findMarksAt(e),n=0;n0;i--)n.context=n.context.prev;return T(e,t,n)}function O(e){var t=e.current().toLowerCase();o=v.hasOwnProperty(t)?"atom":g.hasOwnProperty(t)?"keyword":"variable"}var E={top:function(e,t,n){if("{"==e)return L(n,t,"block");if("}"==e&&n.context.prev)return M(n);if(x&&/@component/i.test(e))return L(n,t,"atComponentBlock");if(/^@(-moz-)?document$/i.test(e))return L(n,t,"documentTypes");if(/^@(media|supports|(-moz-)?document|import)$/i.test(e))return L(n,t,"atBlock");if(/^@(font-face|counter-style)/i.test(e))return n.stateArg=e,"restricted_atBlock_before";if(/^@(-(moz|ms|o|webkit)-)?keyframes$/i.test(e))return"keyframes";if(e&&"@"==e.charAt(0))return L(n,t,"at");if("hash"==e)o="builtin";else if("word"==e)o="tag";else{if("variable-definition"==e)return"maybeprop";if("interpolation"==e)return L(n,t,"interpolation");if(":"==e)return"pseudo";if(y&&"("==e)return L(n,t,"parens")}return n.context.type},block:function(e,t,n){if("word"==e){var r=t.current().toLowerCase();return d.hasOwnProperty(r)?(o="property","maybeprop"):h.hasOwnProperty(r)?(o="string-2","maybeprop"):y?(o=t.match(/^\s*:(?:\s|$)/,!1)?"property":"tag","block"):(o+=" error","maybeprop")}return"meta"==e?"block":y||"hash"!=e&&"qualifier"!=e?E.top(e,t,n):(o="error","block")},maybeprop:function(e,t,n){return":"==e?L(n,t,"prop"):T(e,t,n)},prop:function(e,t,n){if(";"==e)return M(n);if("{"==e&&y)return L(n,t,"propBlock");if("}"==e||"{"==e)return A(e,t,n);if("("==e)return L(n,t,"parens");if("hash"!=e||/^#([0-9a-fA-f]{3,4}|[0-9a-fA-f]{6}|[0-9a-fA-f]{8})$/.test(t.current())){if("word"==e)O(t);else if("interpolation"==e)return L(n,t,"interpolation")}else o+=" error";return"prop"},propBlock:function(e,t,n){return"}"==e?M(n):"word"==e?(o="property","maybeprop"):n.context.type},parens:function(e,t,n){return"{"==e||"}"==e?A(e,t,n):")"==e?M(n):"("==e?L(n,t,"parens"):"interpolation"==e?L(n,t,"interpolation"):("word"==e&&O(t),"parens")},pseudo:function(e,t,n){return"meta"==e?"pseudo":"word"==e?(o="variable-3",n.context.type):T(e,t,n)},documentTypes:function(e,t,n){return"word"==e&&s.hasOwnProperty(t.current())?(o="tag",n.context.type):E.atBlock(e,t,n)},atBlock:function(e,t,n){if("("==e)return L(n,t,"atBlock_parens");if("}"==e||";"==e)return A(e,t,n);if("{"==e)return M(n)&&L(n,t,y?"block":"top");if("interpolation"==e)return L(n,t,"interpolation");if("word"==e){var r=t.current().toLowerCase();o="only"==r||"not"==r||"and"==r||"or"==r?"keyword":c.hasOwnProperty(r)?"attribute":u.hasOwnProperty(r)?"property":f.hasOwnProperty(r)?"keyword":d.hasOwnProperty(r)?"property":h.hasOwnProperty(r)?"string-2":v.hasOwnProperty(r)?"atom":g.hasOwnProperty(r)?"keyword":"error"}return n.context.type},atComponentBlock:function(e,t,n){return"}"==e?A(e,t,n):"{"==e?M(n)&&L(n,t,y?"block":"top",!1):("word"==e&&(o="error"),n.context.type)},atBlock_parens:function(e,t,n){return")"==e?M(n):"{"==e||"}"==e?A(e,t,n,2):E.atBlock(e,t,n)},restricted_atBlock_before:function(e,t,n){return"{"==e?L(n,t,"restricted_atBlock"):"word"==e&&"@counter-style"==n.stateArg?(o="variable","restricted_atBlock_before"):T(e,t,n)},restricted_atBlock:function(e,t,n){return"}"==e?(n.stateArg=null,M(n)):"word"==e?(o="@font-face"==n.stateArg&&!p.hasOwnProperty(t.current().toLowerCase())||"@counter-style"==n.stateArg&&!m.hasOwnProperty(t.current().toLowerCase())?"error":"property","maybeprop"):"restricted_atBlock"},keyframes:function(e,t,n){return"word"==e?(o="variable","keyframes"):"{"==e?L(n,t,"top"):T(e,t,n)},at:function(e,t,n){return";"==e?M(n):"{"==e||"}"==e?A(e,t,n):("word"==e?o="tag":"hash"==e&&(o="builtin"),"at")},interpolation:function(e,t,n){return"}"==e?M(n):"{"==e||";"==e?A(e,t,n):("word"==e?o="variable":"variable"!=e&&"("!=e&&")"!=e&&(o="error"),"interpolation")}};return{startState:function(e){return{tokenize:null,state:r?"block":"top",stateArg:null,context:new S(r?"block":"top",e||0,null)}},token:function(e,t){if(!t.tokenize&&e.eatSpace())return null;var n=(t.tokenize||function(e,t){var n=e.next();if(l[n]){var r=l[n](e,t);if(!1!==r)return r}return"@"==n?(e.eatWhile(/[\w\\\-]/),w("def",e.current())):"="==n||("~"==n||"|"==n)&&e.eat("=")?w(null,"compare"):'"'==n||"'"==n?(t.tokenize=k(n),t.tokenize(e,t)):"#"==n?(e.eatWhile(/[\w\\\-]/),w("atom","hash")):"!"==n?(e.match(/^\s*\w*/),w("keyword","important")):/\d/.test(n)||"."==n&&e.eat(/\d/)?(e.eatWhile(/[\w.%]/),w("number","unit")):"-"!==n?/[,+>*\/]/.test(n)?w(null,"select-op"):"."==n&&e.match(/^-?[_a-z][_a-z0-9-]*/i)?w("qualifier","qualifier"):/[:;{}\[\]\(\)]/.test(n)?w(null,n):("u"==n||"U"==n)&&e.match(/rl(-prefix)?\(/i)||("d"==n||"D"==n)&&e.match("omain(",!0,!0)||("r"==n||"R"==n)&&e.match("egexp(",!0,!0)?(e.backUp(1),t.tokenize=C,w("property","word")):/[\w\\\-]/.test(n)?(e.eatWhile(/[\w\\\-]/),w("property","word")):w(null,null):/[\d.]/.test(e.peek())?(e.eatWhile(/[\w.%]/),w("number","unit")):e.match(/^-[\w\\\-]+/)?(e.eatWhile(/[\w\\\-]/),e.match(/^\s*:/,!1)?w("variable-2","variable-definition"):w("variable-2","variable")):e.match(/^\w+-/)?w("meta","meta"):void 0})(e,t);return n&&"object"==typeof n&&(i=n[1],n=n[0]),o=n,"comment"!=i&&(t.state=E[t.state](i,e,t)),o},indent:function(e,t){var n=e.context,r=t&&t.charAt(0),i=n.indent;return"prop"!=n.type||"}"!=r&&")"!=r||(n=n.prev),n.prev&&("}"!=r||"block"!=n.type&&"top"!=n.type&&"interpolation"!=n.type&&"restricted_atBlock"!=n.type?(")"!=r||"parens"!=n.type&&"atBlock_parens"!=n.type)&&("{"!=r||"at"!=n.type&&"atBlock"!=n.type)||(i=Math.max(0,n.indent-a)):(n=n.prev,i=n.indent)),i},electricChars:"}",blockCommentStart:"/*",blockCommentEnd:"*/",blockCommentContinue:" * ",lineComment:b,fold:"brace"}});var n=["domain","regexp","url","url-prefix"],r=t(n),i=["all","aural","braille","handheld","print","projection","screen","tty","tv","embossed"],o=t(i),a=["width","min-width","max-width","height","min-height","max-height","device-width","min-device-width","max-device-width","device-height","min-device-height","max-device-height","aspect-ratio","min-aspect-ratio","max-aspect-ratio","device-aspect-ratio","min-device-aspect-ratio","max-device-aspect-ratio","color","min-color","max-color","color-index","min-color-index","max-color-index","monochrome","min-monochrome","max-monochrome","resolution","min-resolution","max-resolution","scan","grid","orientation","device-pixel-ratio","min-device-pixel-ratio","max-device-pixel-ratio","pointer","any-pointer","hover","any-hover"],l=t(a),s=["landscape","portrait","none","coarse","fine","on-demand","hover","interlace","progressive"],c=t(s),u=["align-content","align-items","align-self","alignment-adjust","alignment-baseline","anchor-point","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","appearance","azimuth","backface-visibility","background","background-attachment","background-blend-mode","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","baseline-shift","binding","bleed","bookmark-label","bookmark-level","bookmark-state","bookmark-target","border","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","break-after","break-before","break-inside","caption-side","caret-color","clear","clip","color","color-profile","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","content","counter-increment","counter-reset","crop","cue","cue-after","cue-before","cursor","direction","display","dominant-baseline","drop-initial-after-adjust","drop-initial-after-align","drop-initial-before-adjust","drop-initial-before-align","drop-initial-size","drop-initial-value","elevation","empty-cells","fit","fit-position","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","float-offset","flow-from","flow-into","font","font-feature-settings","font-family","font-kerning","font-language-override","font-size","font-size-adjust","font-stretch","font-style","font-synthesis","font-variant","font-variant-alternates","font-variant-caps","font-variant-east-asian","font-variant-ligatures","font-variant-numeric","font-variant-position","font-weight","grid","grid-area","grid-auto-columns","grid-auto-flow","grid-auto-rows","grid-column","grid-column-end","grid-column-gap","grid-column-start","grid-gap","grid-row","grid-row-end","grid-row-gap","grid-row-start","grid-template","grid-template-areas","grid-template-columns","grid-template-rows","hanging-punctuation","height","hyphens","icon","image-orientation","image-rendering","image-resolution","inline-box-align","justify-content","justify-items","justify-self","left","letter-spacing","line-break","line-height","line-stacking","line-stacking-ruby","line-stacking-shift","line-stacking-strategy","list-style","list-style-image","list-style-position","list-style-type","margin","margin-bottom","margin-left","margin-right","margin-top","marks","marquee-direction","marquee-loop","marquee-play-count","marquee-speed","marquee-style","max-height","max-width","min-height","min-width","move-to","nav-down","nav-index","nav-left","nav-right","nav-up","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-style","overflow-wrap","overflow-x","overflow-y","padding","padding-bottom","padding-left","padding-right","padding-top","page","page-break-after","page-break-before","page-break-inside","page-policy","pause","pause-after","pause-before","perspective","perspective-origin","pitch","pitch-range","place-content","place-items","place-self","play-during","position","presentation-level","punctuation-trim","quotes","region-break-after","region-break-before","region-break-inside","region-fragment","rendering-intent","resize","rest","rest-after","rest-before","richness","right","rotation","rotation-point","ruby-align","ruby-overhang","ruby-position","ruby-span","shape-image-threshold","shape-inside","shape-margin","shape-outside","size","speak","speak-as","speak-header","speak-numeral","speak-punctuation","speech-rate","stress","string-set","tab-size","table-layout","target","target-name","target-new","target-position","text-align","text-align-last","text-decoration","text-decoration-color","text-decoration-line","text-decoration-skip","text-decoration-style","text-emphasis","text-emphasis-color","text-emphasis-position","text-emphasis-style","text-height","text-indent","text-justify","text-outline","text-overflow","text-shadow","text-size-adjust","text-space-collapse","text-transform","text-underline-position","text-wrap","top","transform","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","user-select","vertical-align","visibility","voice-balance","voice-duration","voice-family","voice-pitch","voice-range","voice-rate","voice-stress","voice-volume","volume","white-space","widows","width","will-change","word-break","word-spacing","word-wrap","z-index","clip-path","clip-rule","mask","enable-background","filter","flood-color","flood-opacity","lighting-color","stop-color","stop-opacity","pointer-events","color-interpolation","color-interpolation-filters","color-rendering","fill","fill-opacity","fill-rule","image-rendering","marker","marker-end","marker-mid","marker-start","shape-rendering","stroke","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","text-rendering","baseline-shift","dominant-baseline","glyph-orientation-horizontal","glyph-orientation-vertical","text-anchor","writing-mode"],f=t(u),d=["scrollbar-arrow-color","scrollbar-base-color","scrollbar-dark-shadow-color","scrollbar-face-color","scrollbar-highlight-color","scrollbar-shadow-color","scrollbar-3d-light-color","scrollbar-track-color","shape-inside","searchfield-cancel-button","searchfield-decoration","searchfield-results-button","searchfield-results-decoration","zoom"],h=t(d),p=t(["font-family","src","unicode-range","font-variant","font-feature-settings","font-stretch","font-weight","font-style"]),m=t(["additive-symbols","fallback","negative","pad","prefix","range","speak-as","suffix","symbols","system"]),g=["aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgreen","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","grey","green","greenyellow","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgreen","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen"],v=t(g),y=["above","absolute","activeborder","additive","activecaption","afar","after-white-space","ahead","alias","all","all-scroll","alphabetic","alternate","always","amharic","amharic-abegede","antialiased","appworkspace","arabic-indic","armenian","asterisks","attr","auto","auto-flow","avoid","avoid-column","avoid-page","avoid-region","background","backwards","baseline","below","bidi-override","binary","bengali","blink","block","block-axis","bold","bolder","border","border-box","both","bottom","break","break-all","break-word","bullets","button","button-bevel","buttonface","buttonhighlight","buttonshadow","buttontext","calc","cambodian","capitalize","caps-lock-indicator","caption","captiontext","caret","cell","center","checkbox","circle","cjk-decimal","cjk-earthly-branch","cjk-heavenly-stem","cjk-ideographic","clear","clip","close-quote","col-resize","collapse","color","color-burn","color-dodge","column","column-reverse","compact","condensed","contain","content","contents","content-box","context-menu","continuous","copy","counter","counters","cover","crop","cross","crosshair","currentcolor","cursive","cyclic","darken","dashed","decimal","decimal-leading-zero","default","default-button","dense","destination-atop","destination-in","destination-out","destination-over","devanagari","difference","disc","discard","disclosure-closed","disclosure-open","document","dot-dash","dot-dot-dash","dotted","double","down","e-resize","ease","ease-in","ease-in-out","ease-out","element","ellipse","ellipsis","embed","end","ethiopic","ethiopic-abegede","ethiopic-abegede-am-et","ethiopic-abegede-gez","ethiopic-abegede-ti-er","ethiopic-abegede-ti-et","ethiopic-halehame-aa-er","ethiopic-halehame-aa-et","ethiopic-halehame-am-et","ethiopic-halehame-gez","ethiopic-halehame-om-et","ethiopic-halehame-sid-et","ethiopic-halehame-so-et","ethiopic-halehame-ti-er","ethiopic-halehame-ti-et","ethiopic-halehame-tig","ethiopic-numeric","ew-resize","exclusion","expanded","extends","extra-condensed","extra-expanded","fantasy","fast","fill","fixed","flat","flex","flex-end","flex-start","footnotes","forwards","from","geometricPrecision","georgian","graytext","grid","groove","gujarati","gurmukhi","hand","hangul","hangul-consonant","hard-light","hebrew","help","hidden","hide","higher","highlight","highlighttext","hiragana","hiragana-iroha","horizontal","hsl","hsla","hue","icon","ignore","inactiveborder","inactivecaption","inactivecaptiontext","infinite","infobackground","infotext","inherit","initial","inline","inline-axis","inline-block","inline-flex","inline-grid","inline-table","inset","inside","intrinsic","invert","italic","japanese-formal","japanese-informal","justify","kannada","katakana","katakana-iroha","keep-all","khmer","korean-hangul-formal","korean-hanja-formal","korean-hanja-informal","landscape","lao","large","larger","left","level","lighter","lighten","line-through","linear","linear-gradient","lines","list-item","listbox","listitem","local","logical","loud","lower","lower-alpha","lower-armenian","lower-greek","lower-hexadecimal","lower-latin","lower-norwegian","lower-roman","lowercase","ltr","luminosity","malayalam","match","matrix","matrix3d","media-controls-background","media-current-time-display","media-fullscreen-button","media-mute-button","media-play-button","media-return-to-realtime-button","media-rewind-button","media-seek-back-button","media-seek-forward-button","media-slider","media-sliderthumb","media-time-remaining-display","media-volume-slider","media-volume-slider-container","media-volume-sliderthumb","medium","menu","menulist","menulist-button","menulist-text","menulist-textfield","menutext","message-box","middle","min-intrinsic","mix","mongolian","monospace","move","multiple","multiply","myanmar","n-resize","narrower","ne-resize","nesw-resize","no-close-quote","no-drop","no-open-quote","no-repeat","none","normal","not-allowed","nowrap","ns-resize","numbers","numeric","nw-resize","nwse-resize","oblique","octal","opacity","open-quote","optimizeLegibility","optimizeSpeed","oriya","oromo","outset","outside","outside-shape","overlay","overline","padding","padding-box","painted","page","paused","persian","perspective","plus-darker","plus-lighter","pointer","polygon","portrait","pre","pre-line","pre-wrap","preserve-3d","progress","push-button","radial-gradient","radio","read-only","read-write","read-write-plaintext-only","rectangle","region","relative","repeat","repeating-linear-gradient","repeating-radial-gradient","repeat-x","repeat-y","reset","reverse","rgb","rgba","ridge","right","rotate","rotate3d","rotateX","rotateY","rotateZ","round","row","row-resize","row-reverse","rtl","run-in","running","s-resize","sans-serif","saturation","scale","scale3d","scaleX","scaleY","scaleZ","screen","scroll","scrollbar","scroll-position","se-resize","searchfield","searchfield-cancel-button","searchfield-decoration","searchfield-results-button","searchfield-results-decoration","self-start","self-end","semi-condensed","semi-expanded","separate","serif","show","sidama","simp-chinese-formal","simp-chinese-informal","single","skew","skewX","skewY","skip-white-space","slide","slider-horizontal","slider-vertical","sliderthumb-horizontal","sliderthumb-vertical","slow","small","small-caps","small-caption","smaller","soft-light","solid","somali","source-atop","source-in","source-out","source-over","space","space-around","space-between","space-evenly","spell-out","square","square-button","start","static","status-bar","stretch","stroke","sub","subpixel-antialiased","super","sw-resize","symbolic","symbols","system-ui","table","table-caption","table-cell","table-column","table-column-group","table-footer-group","table-header-group","table-row","table-row-group","tamil","telugu","text","text-bottom","text-top","textarea","textfield","thai","thick","thin","threeddarkshadow","threedface","threedhighlight","threedlightshadow","threedshadow","tibetan","tigre","tigrinya-er","tigrinya-er-abegede","tigrinya-et","tigrinya-et-abegede","to","top","trad-chinese-formal","trad-chinese-informal","transform","translate","translate3d","translateX","translateY","translateZ","transparent","ultra-condensed","ultra-expanded","underline","unset","up","upper-alpha","upper-armenian","upper-greek","upper-hexadecimal","upper-latin","upper-norwegian","upper-roman","uppercase","urdu","url","var","vertical","vertical-text","visible","visibleFill","visiblePainted","visibleStroke","visual","w-resize","wait","wave","wider","window","windowframe","windowtext","words","wrap","wrap-reverse","x-large","x-small","xor","xx-large","xx-small"],b=t(y),x=n.concat(i).concat(a).concat(s).concat(u).concat(d).concat(g).concat(y);function w(e,t){for(var n,r=!1;null!=(n=e.next());){if(r&&"/"==n){t.tokenize=null;break}r="*"==n}return["comment","comment"]}e.registerHelper("hintWords","css",x),e.defineMIME("text/css",{documentTypes:r,mediaTypes:o,mediaFeatures:l,mediaValueKeywords:c,propertyKeywords:f,nonStandardPropertyKeywords:h,fontProperties:p,counterDescriptors:m,colorKeywords:v,valueKeywords:b,tokenHooks:{"/":function(e,t){return!!e.eat("*")&&(t.tokenize=w,w(e,t))}},name:"css"}),e.defineMIME("text/x-scss",{mediaTypes:o,mediaFeatures:l,mediaValueKeywords:c,propertyKeywords:f,nonStandardPropertyKeywords:h,colorKeywords:v,valueKeywords:b,fontProperties:p,allowNested:!0,lineComment:"//",tokenHooks:{"/":function(e,t){return e.eat("/")?(e.skipToEnd(),["comment","comment"]):e.eat("*")?(t.tokenize=w,w(e,t)):["operator","operator"]},":":function(e){return!!e.match(/\s*\{/,!1)&&[null,null]},$:function(e){return e.match(/^[\w-]+/),e.match(/^\s*:/,!1)?["variable-2","variable-definition"]:["variable-2","variable"]},"#":function(e){return!!e.eat("{")&&[null,"interpolation"]}},name:"css",helperType:"scss"}),e.defineMIME("text/x-less",{mediaTypes:o,mediaFeatures:l,mediaValueKeywords:c,propertyKeywords:f,nonStandardPropertyKeywords:h,colorKeywords:v,valueKeywords:b,fontProperties:p,allowNested:!0,lineComment:"//",tokenHooks:{"/":function(e,t){return e.eat("/")?(e.skipToEnd(),["comment","comment"]):e.eat("*")?(t.tokenize=w,w(e,t)):["operator","operator"]},"@":function(e){return e.eat("{")?[null,"interpolation"]:!e.match(/^(charset|document|font-face|import|(-(moz|ms|o|webkit)-)?keyframes|media|namespace|page|supports)\b/i,!1)&&(e.eatWhile(/[\w\\\-]/),e.match(/^\s*:/,!1)?["variable-2","variable-definition"]:["variable-2","variable"])},"&":function(){return["atom","atom"]}},name:"css",helperType:"less"}),e.defineMIME("text/x-gss",{documentTypes:r,mediaTypes:o,mediaFeatures:l,propertyKeywords:f,nonStandardPropertyKeywords:h,fontProperties:p,counterDescriptors:m,colorKeywords:v,valueKeywords:b,supportsAtComponent:!0,tokenHooks:{"/":function(e,t){return!!e.eat("*")&&(t.tokenize=w,w(e,t))}},name:"css",helperType:"gss"})}(n(0))},function(e,t,n){!function(e){"use strict";e.runMode=function(t,n,r,i){var o=e.getMode(e.defaults,n),a=/MSIE \d/.test(navigator.userAgent),l=a&&(null==document.documentMode||document.documentMode<9);if(r.appendChild){var s=i&&i.tabSize||e.defaults.tabSize,c=r,u=0;c.innerHTML="",r=function(e,t){if("\n"==e)return c.appendChild(document.createTextNode(l?"\r":e)),void(u=0);for(var n="",r=0;;){var i=e.indexOf("\t",r);if(-1==i){n+=e.slice(r),u+=e.length-r;break}u+=i-r,n+=e.slice(r,i);var o=s-u%s;u+=o;for(var a=0;a=s&&(o=r(a.indicatorOpen))}e.setGutterMarker(i,a.gutter,o),++l})}function o(e){var t=e.getViewport(),n=e.state.foldGutter;n&&(e.operation(function(){i(e,t.from,t.to)}),n.from=t.from,n.to=t.to)}function a(e,r,i){var o=e.state.foldGutter;if(o){var a=o.options;if(i==a.gutter){var l=n(e,r);l?l.clear():e.foldCode(t(r,0),a.rangeFinder)}}}function l(e){var t=e.state.foldGutter;if(t){var n=t.options;t.from=t.to=0,clearTimeout(t.changeUpdate),t.changeUpdate=setTimeout(function(){o(e)},n.foldOnChangeTimeSpan||600)}}function s(e){var t=e.state.foldGutter;if(t){var n=t.options;clearTimeout(t.changeUpdate),t.changeUpdate=setTimeout(function(){var n=e.getViewport();t.from==t.to||n.from-t.to>20||t.from-n.to>20?o(e):e.operation(function(){n.fromt.to&&(i(e,t.to,n.to),t.to=n.to)})},n.updateViewportTimeSpan||400)}}function c(e,t){var n=e.state.foldGutter;if(n){var r=t.line;r>=n.from&&r=e.max))return e.ch=0,e.text=e.cm.getLine(++e.line),!0}function s(e){if(!(e.line<=e.min))return e.text=e.cm.getLine(--e.line),e.ch=e.text.length,!0}function c(e){for(;;){var t=e.text.indexOf(">",e.ch);if(-1==t){if(l(e))continue;return}if(a(e,t+1)){var n=e.text.lastIndexOf("/",t),r=n>-1&&!/\S/.test(e.text.slice(n+1,t));return e.ch=t+1,r?"selfClose":"regular"}e.ch=t+1}}function u(e){for(;;){var t=e.ch?e.text.lastIndexOf("<",e.ch-1):-1;if(-1==t){if(s(e))continue;return}if(a(e,t+1)){i.lastIndex=t,e.ch=t;var n=i.exec(e.text);if(n&&n.index==t)return n}else e.ch=t}}function f(e){for(;;){i.lastIndex=e.ch;var t=i.exec(e.text);if(!t){if(l(e))continue;return}if(a(e,t.index+1))return e.ch=t.index+t[0].length,t;e.ch=t.index+1}}function d(e){for(;;){var t=e.ch?e.text.lastIndexOf(">",e.ch-1):-1;if(-1==t){if(s(e))continue;return}if(a(e,t+1)){var n=e.text.lastIndexOf("/",t),r=n>-1&&!/\S/.test(e.text.slice(n+1,t));return e.ch=t+1,r?"selfClose":"regular"}e.ch=t}}function h(e,n){for(var r=[];;){var i,o=f(e),a=e.line,l=e.ch-(o?o[0].length:0);if(!o||!(i=c(e)))return;if("selfClose"!=i)if(o[1]){for(var s=r.length-1;s>=0;--s)if(r[s]==o[2]){r.length=s;break}if(s<0&&(!n||n==o[2]))return{tag:o[2],from:t(a,l),to:t(e.line,e.ch)}}else r.push(o[2])}}function p(e,n){for(var r=[];;){var i=d(e);if(!i)return;if("selfClose"!=i){var o=e.line,a=e.ch,l=u(e);if(!l)return;if(l[1])r.push(l[2]);else{for(var s=r.length-1;s>=0;--s)if(r[s]==l[2]){r.length=s;break}if(s<0&&(!n||n==l[2]))return{tag:l[2],from:t(e.line,e.ch),to:t(o,a)}}}else u(e)}}e.registerHelper("fold","xml",function(e,r){for(var i=new o(e,r.line,0);;){var a=f(i);if(!a||i.line!=r.line)return;var l=c(i);if(!l)return;if(!a[1]&&"selfClose"!=l){var s=t(i.line,i.ch),u=h(i,a[2]);return u&&n(u.from,s)>0?{from:s,to:u.from}:null}}}),e.findMatchingTag=function(e,r,i){var a=new o(e,r.line,r.ch,i);if(-1!=a.text.indexOf(">")||-1!=a.text.indexOf("<")){var l=c(a),s=l&&t(a.line,a.ch),f=l&&u(a);if(l&&f&&!(n(a,r)>0)){var d={from:t(a.line,a.ch),to:s,tag:f[2]};return"selfClose"==l?{open:d,close:null,at:"open"}:f[1]?{open:p(a,f[2]),close:d,at:"close"}:(a=new o(e,s.line,s.ch,i),{open:d,close:h(a,f[2]),at:"open"})}}},e.findEnclosingTag=function(e,t,n,r){for(var i=new o(e,t.line,t.ch,n);;){var a=p(i,r);if(!a)break;var l=new o(e,t.line,t.ch,n),s=h(l,a.tag);if(s)return{open:a,close:s}}},e.scanForClosingTag=function(e,t,n,r){var i=new o(e,t.line,t.ch,r?{from:0,to:r}:null);return h(i,n)}}(n(0))},function(e,t,n){!function(e){"use strict";e.registerGlobalHelper("fold","comment",function(e){return e.blockCommentStart&&e.blockCommentEnd},function(t,n){var r=t.getModeAt(n),i=r.blockCommentStart,o=r.blockCommentEnd;if(i&&o){for(var a,l=n.line,s=t.getLine(l),c=n.ch,u=0;;){var f=c<=0?-1:s.lastIndexOf(i,c-1);if(-1!=f){if(1==u&&ft.lastLine())return null;var r=t.getTokenAt(e.Pos(n,1));if(/\S/.test(r.string)||(r=t.getTokenAt(e.Pos(n,r.end+1))),"keyword"!=r.type||"import"!=r.string)return null;for(var i=n,o=Math.min(t.lastLine(),n+10);i<=o;++i){var a=t.getLine(i),l=a.indexOf(";");if(-1!=l)return{startCh:r.end,end:e.Pos(i,l)}}}var i,o=n.line,a=r(o);if(!a||r(o-1)||(i=r(o-2))&&i.end.line==o-1)return null;for(var l=a.end;;){var s=r(l.line+1);if(null==s)break;l=s.end}return{from:t.clipPos(e.Pos(o,a.startCh+1)),to:l}}),e.registerHelper("fold","include",function(t,n){function r(n){if(nt.lastLine())return null;var r=t.getTokenAt(e.Pos(n,1));return/\S/.test(r.string)||(r=t.getTokenAt(e.Pos(n,r.end+1))),"meta"==r.type&&"#include"==r.string.slice(0,8)?r.start+8:void 0}var i=n.line,o=r(i);if(null==o||null!=r(i-1))return null;for(var a=i;;){var l=r(a+1);if(null==l)break;++a}return{from:e.Pos(i,o+1),to:t.clipPos(e.Pos(a))}})}(n(0))},function(e,t,n){!function(e){"use strict";var t=e.commands,n=e.Pos;function r(t,r){t.extendSelectionsBy(function(i){return t.display.shift||t.doc.extend||i.empty()?function(t,r,i){if(i<0&&0==r.ch)return t.clipPos(n(r.line-1));var o=t.getLine(r.line);if(i>0&&r.ch>=o.length)return t.clipPos(n(r.line+1,0));for(var a,l="start",s=r.ch,c=i<0?0:o.length,u=0;s!=c;s+=i,u++){var f=o.charAt(i<0?s-1:s),d="_"!=f&&e.isWordChar(f)?"w":"o";if("w"==d&&f.toUpperCase()==f&&(d="W"),"start"==l)"o"!=d&&(l="in",a=d);else if("in"==l&&a!=d){if("w"==a&&"W"==d&&i<0&&s--,"W"==a&&"w"==d&&i>0){a="w";continue}break}}return n(r.line,s)}(t.doc,i.head,r):r<0?i.from():i.to()})}function i(t,r){if(t.isReadOnly())return e.Pass;t.operation(function(){for(var e=t.listSelections().length,i=[],o=-1,a=0;a=n&&e.execCommand("goLineUp")}e.scrollTo(null,t.top-e.defaultTextHeight())},t.scrollLineDown=function(e){var t=e.getScrollInfo();if(!e.somethingSelected()){var n=e.lineAtHeight(t.top,"local")+1;e.getCursor().line<=n&&e.execCommand("goLineDown")}e.scrollTo(null,t.top+e.defaultTextHeight())},t.splitSelectionByLine=function(e){for(var t=e.listSelections(),r=[],i=0;io.line&&l==a.line&&0==a.ch||r.push({anchor:l==o.line?o:n(l,0),head:l==a.line?a:n(l)});e.setSelections(r,0)},t.singleSelectionTop=function(e){var t=e.listSelections()[0];e.setSelection(t.anchor,t.head,{scroll:!1})},t.selectLine=function(e){for(var t=e.listSelections(),r=[],i=0;i=0;l--){var s=r[i[l]];if(!(c&&e.cmpPos(s.head,c)>0)){var u=o(t,s.head);c=u.from,t.replaceRange(n(u.word),u.from,u.to)}}})}function f(t){var n=t.getCursor("from"),r=t.getCursor("to");if(0==e.cmpPos(n,r)){var i=o(t,n);if(!i.word)return;n=i.from,r=i.to}return{from:n,to:r,query:t.getRange(n,r),word:i}}function d(e,t){var r=f(e);if(r){var i=r.query,o=e.getSearchCursor(i,t?r.to:r.from);(t?o.findNext():o.findPrevious())?e.setSelection(o.from(),o.to()):(o=e.getSearchCursor(i,t?n(e.firstLine(),0):e.clipPos(n(e.lastLine()))),(t?o.findNext():o.findPrevious())?e.setSelection(o.from(),o.to()):r.word&&e.setSelection(r.from,r.to))}}t.selectScope=function(e){s(e)||e.execCommand("selectAll")},t.selectBetweenBrackets=function(t){if(!s(t))return e.Pass},t.goToBracket=function(t){t.extendSelectionsBy(function(r){var i=t.scanForBracket(r.head,1);if(i&&0!=e.cmpPos(i.pos,r.head))return i.pos;var o=t.scanForBracket(r.head,-1);return o&&n(o.pos.line,o.pos.ch+1)||r.head})},t.swapLineUp=function(t){if(t.isReadOnly())return e.Pass;for(var r=t.listSelections(),i=[],o=t.firstLine()-1,a=[],l=0;lo?i.push(c,u):i.length&&(i[i.length-1]=u),o=u}t.operation(function(){for(var e=0;et.lastLine()?t.replaceRange("\n"+l,n(t.lastLine()),null,"+swapLine"):t.replaceRange(l+"\n",n(o,0),null,"+swapLine")}t.setSelections(a),t.scrollIntoView()})},t.swapLineDown=function(t){if(t.isReadOnly())return e.Pass;for(var r=t.listSelections(),i=[],o=t.lastLine()+1,a=r.length-1;a>=0;a--){var l=r[a],s=l.to().line+1,c=l.from().line;0!=l.to().ch||l.empty()||s--,s=0;e-=2){var r=i[e],o=i[e+1],a=t.getLine(r);r==t.lastLine()?t.replaceRange("",n(r-1),n(r),"+swapLine"):t.replaceRange("",n(r,0),n(r+1,0),"+swapLine"),t.replaceRange(a+"\n",n(o,0),null,"+swapLine")}t.scrollIntoView()})},t.toggleCommentIndented=function(e){e.toggleComment({indent:!0})},t.joinLines=function(e){for(var t=e.listSelections(),r=[],i=0;i=0;o--){var a=r[o].head,l=t.getRange({line:a.line,ch:0},a),s=e.countColumn(l,null,t.getOption("tabSize")),c=t.findPosH(a,-1,"char",!1);if(l&&!/\S/.test(l)&&s%i==0){var u=new n(a.line,e.findColumn(l,s-i,i));u.ch!=a.ch&&(c=u)}t.replaceRange("",c,a,"+delete")}})},t.delLineRight=function(e){e.operation(function(){for(var t=e.listSelections(),r=t.length-1;r>=0;r--)e.replaceRange("",t[r].anchor,n(t[r].to().line),"+delete");e.scrollIntoView()})},t.upcaseAtCursor=function(e){u(e,function(e){return e.toUpperCase()})},t.downcaseAtCursor=function(e){u(e,function(e){return e.toLowerCase()})},t.setSublimeMark=function(e){e.state.sublimeMark&&e.state.sublimeMark.clear(),e.state.sublimeMark=e.setBookmark(e.getCursor())},t.selectToSublimeMark=function(e){var t=e.state.sublimeMark&&e.state.sublimeMark.find();t&&e.setSelection(e.getCursor(),t)},t.deleteToSublimeMark=function(t){var n=t.state.sublimeMark&&t.state.sublimeMark.find();if(n){var r=t.getCursor(),i=n;if(e.cmpPos(r,i)>0){var o=i;i=r,r=o}t.state.sublimeKilled=t.getRange(r,i),t.replaceRange("",r,i)}},t.swapWithSublimeMark=function(e){var t=e.state.sublimeMark&&e.state.sublimeMark.find();t&&(e.state.sublimeMark.clear(),e.state.sublimeMark=e.setBookmark(e.getCursor()),e.setCursor(t))},t.sublimeYank=function(e){null!=e.state.sublimeKilled&&e.replaceSelection(e.state.sublimeKilled,null,"paste")},t.showInCenter=function(e){var t=e.cursorCoords(null,"local");e.scrollTo(null,(t.top+t.bottom)/2-e.getScrollInfo().clientHeight/2)},t.findUnder=function(e){d(e,!0)},t.findUnderPrevious=function(e){d(e,!1)},t.findAllUnder=function(e){var t=f(e);if(t){for(var n=e.getSearchCursor(t.query),r=[],i=-1;n.findNext();)r.push({anchor:n.from(),head:n.to()}),n.from().line<=t.from.line&&n.from().ch<=t.from.ch&&i++;e.setSelections(r,i)}};var h=e.keyMap;h.macSublime={"Cmd-Left":"goLineStartSmart","Shift-Tab":"indentLess","Shift-Ctrl-K":"deleteLine","Alt-Q":"wrapLines","Ctrl-Left":"goSubwordLeft","Ctrl-Right":"goSubwordRight","Ctrl-Alt-Up":"scrollLineUp","Ctrl-Alt-Down":"scrollLineDown","Cmd-L":"selectLine","Shift-Cmd-L":"splitSelectionByLine",Esc:"singleSelectionTop","Cmd-Enter":"insertLineAfter","Shift-Cmd-Enter":"insertLineBefore","Cmd-D":"selectNextOccurrence","Shift-Cmd-Space":"selectScope","Shift-Cmd-M":"selectBetweenBrackets","Cmd-M":"goToBracket","Cmd-Ctrl-Up":"swapLineUp","Cmd-Ctrl-Down":"swapLineDown","Cmd-/":"toggleCommentIndented","Cmd-J":"joinLines","Shift-Cmd-D":"duplicateLine",F9:"sortLines","Cmd-F9":"sortLinesInsensitive",F2:"nextBookmark","Shift-F2":"prevBookmark","Cmd-F2":"toggleBookmark","Shift-Cmd-F2":"clearBookmarks","Alt-F2":"selectBookmarks",Backspace:"smartBackspace","Cmd-K Cmd-K":"delLineRight","Cmd-K Cmd-U":"upcaseAtCursor","Cmd-K Cmd-L":"downcaseAtCursor","Cmd-K Cmd-Space":"setSublimeMark","Cmd-K Cmd-A":"selectToSublimeMark","Cmd-K Cmd-W":"deleteToSublimeMark","Cmd-K Cmd-X":"swapWithSublimeMark","Cmd-K Cmd-Y":"sublimeYank","Cmd-K Cmd-C":"showInCenter","Cmd-K Cmd-G":"clearBookmarks","Cmd-K Cmd-Backspace":"delLineLeft","Cmd-K Cmd-0":"unfoldAll","Cmd-K Cmd-J":"unfoldAll","Ctrl-Shift-Up":"addCursorToPrevLine","Ctrl-Shift-Down":"addCursorToNextLine","Cmd-F3":"findUnder","Shift-Cmd-F3":"findUnderPrevious","Alt-F3":"findAllUnder","Shift-Cmd-[":"fold","Shift-Cmd-]":"unfold","Cmd-I":"findIncremental","Shift-Cmd-I":"findIncrementalReverse","Cmd-H":"replace",F3:"findNext","Shift-F3":"findPrev",fallthrough:"macDefault"},e.normalizeKeyMap(h.macSublime),h.pcSublime={"Shift-Tab":"indentLess","Shift-Ctrl-K":"deleteLine","Alt-Q":"wrapLines","Ctrl-T":"transposeChars","Alt-Left":"goSubwordLeft","Alt-Right":"goSubwordRight","Ctrl-Up":"scrollLineUp","Ctrl-Down":"scrollLineDown","Ctrl-L":"selectLine","Shift-Ctrl-L":"splitSelectionByLine",Esc:"singleSelectionTop","Ctrl-Enter":"insertLineAfter","Shift-Ctrl-Enter":"insertLineBefore","Ctrl-D":"selectNextOccurrence","Shift-Ctrl-Space":"selectScope","Shift-Ctrl-M":"selectBetweenBrackets","Ctrl-M":"goToBracket","Shift-Ctrl-Up":"swapLineUp","Shift-Ctrl-Down":"swapLineDown","Ctrl-/":"toggleCommentIndented","Ctrl-J":"joinLines","Shift-Ctrl-D":"duplicateLine",F9:"sortLines","Ctrl-F9":"sortLinesInsensitive",F2:"nextBookmark","Shift-F2":"prevBookmark","Ctrl-F2":"toggleBookmark","Shift-Ctrl-F2":"clearBookmarks","Alt-F2":"selectBookmarks",Backspace:"smartBackspace","Ctrl-K Ctrl-K":"delLineRight","Ctrl-K Ctrl-U":"upcaseAtCursor","Ctrl-K Ctrl-L":"downcaseAtCursor","Ctrl-K Ctrl-Space":"setSublimeMark","Ctrl-K Ctrl-A":"selectToSublimeMark","Ctrl-K Ctrl-W":"deleteToSublimeMark","Ctrl-K Ctrl-X":"swapWithSublimeMark","Ctrl-K Ctrl-Y":"sublimeYank","Ctrl-K Ctrl-C":"showInCenter","Ctrl-K Ctrl-G":"clearBookmarks","Ctrl-K Ctrl-Backspace":"delLineLeft","Ctrl-K Ctrl-0":"unfoldAll","Ctrl-K Ctrl-J":"unfoldAll","Ctrl-Alt-Up":"addCursorToPrevLine","Ctrl-Alt-Down":"addCursorToNextLine","Ctrl-F3":"findUnder","Shift-Ctrl-F3":"findUnderPrevious","Alt-F3":"findAllUnder","Shift-Ctrl-[":"fold","Shift-Ctrl-]":"unfold","Ctrl-I":"findIncremental","Shift-Ctrl-I":"findIncrementalReverse","Ctrl-H":"replace",F3:"findNext","Shift-F3":"findPrev",fallthrough:"pcDefault"},e.normalizeKeyMap(h.pcSublime);var p=h.default==h.macDefault;h.sublime=p?h.macSublime:h.pcSublime}(n(0),n(1),n(4))},function(e,t,n){!function(e){"use strict";var t=[{keys:"",type:"keyToKey",toKeys:"h"},{keys:"",type:"keyToKey",toKeys:"l"},{keys:"",type:"keyToKey",toKeys:"k"},{keys:"",type:"keyToKey",toKeys:"j"},{keys:"",type:"keyToKey",toKeys:"l"},{keys:"",type:"keyToKey",toKeys:"h",context:"normal"},{keys:"",type:"keyToKey",toKeys:"W"},{keys:"",type:"keyToKey",toKeys:"B",context:"normal"},{keys:"",type:"keyToKey",toKeys:"w"},{keys:"",type:"keyToKey",toKeys:"b",context:"normal"},{keys:"",type:"keyToKey",toKeys:"j"},{keys:"",type:"keyToKey",toKeys:"k"},{keys:"",type:"keyToKey",toKeys:""},{keys:"",type:"keyToKey",toKeys:""},{keys:"",type:"keyToKey",toKeys:"",context:"insert"},{keys:"",type:"keyToKey",toKeys:"",context:"insert"},{keys:"s",type:"keyToKey",toKeys:"cl",context:"normal"},{keys:"s",type:"keyToKey",toKeys:"c",context:"visual"},{keys:"S",type:"keyToKey",toKeys:"cc",context:"normal"},{keys:"S",type:"keyToKey",toKeys:"VdO",context:"visual"},{keys:"",type:"keyToKey",toKeys:"0"},{keys:"",type:"keyToKey",toKeys:"$"},{keys:"",type:"keyToKey",toKeys:""},{keys:"",type:"keyToKey",toKeys:""},{keys:"",type:"keyToKey",toKeys:"j^",context:"normal"},{keys:"",type:"action",action:"toggleOverwrite",context:"insert"},{keys:"H",type:"motion",motion:"moveToTopLine",motionArgs:{linewise:!0,toJumplist:!0}},{keys:"M",type:"motion",motion:"moveToMiddleLine",motionArgs:{linewise:!0,toJumplist:!0}},{keys:"L",type:"motion",motion:"moveToBottomLine",motionArgs:{linewise:!0,toJumplist:!0}},{keys:"h",type:"motion",motion:"moveByCharacters",motionArgs:{forward:!1}},{keys:"l",type:"motion",motion:"moveByCharacters",motionArgs:{forward:!0}},{keys:"j",type:"motion",motion:"moveByLines",motionArgs:{forward:!0,linewise:!0}},{keys:"k",type:"motion",motion:"moveByLines",motionArgs:{forward:!1,linewise:!0}},{keys:"gj",type:"motion",motion:"moveByDisplayLines",motionArgs:{forward:!0}},{keys:"gk",type:"motion",motion:"moveByDisplayLines",motionArgs:{forward:!1}},{keys:"w",type:"motion",motion:"moveByWords",motionArgs:{forward:!0,wordEnd:!1}},{keys:"W",type:"motion",motion:"moveByWords",motionArgs:{forward:!0,wordEnd:!1,bigWord:!0}},{keys:"e",type:"motion",motion:"moveByWords",motionArgs:{forward:!0,wordEnd:!0,inclusive:!0}},{keys:"E",type:"motion",motion:"moveByWords",motionArgs:{forward:!0,wordEnd:!0,bigWord:!0,inclusive:!0}},{keys:"b",type:"motion",motion:"moveByWords",motionArgs:{forward:!1,wordEnd:!1}},{keys:"B",type:"motion",motion:"moveByWords",motionArgs:{forward:!1,wordEnd:!1,bigWord:!0}},{keys:"ge",type:"motion",motion:"moveByWords",motionArgs:{forward:!1,wordEnd:!0,inclusive:!0}},{keys:"gE",type:"motion",motion:"moveByWords",motionArgs:{forward:!1,wordEnd:!0,bigWord:!0,inclusive:!0}},{keys:"{",type:"motion",motion:"moveByParagraph",motionArgs:{forward:!1,toJumplist:!0}},{keys:"}",type:"motion",motion:"moveByParagraph",motionArgs:{forward:!0,toJumplist:!0}},{keys:"(",type:"motion",motion:"moveBySentence",motionArgs:{forward:!1}},{keys:")",type:"motion",motion:"moveBySentence",motionArgs:{forward:!0}},{keys:"",type:"motion",motion:"moveByPage",motionArgs:{forward:!0}},{keys:"",type:"motion",motion:"moveByPage",motionArgs:{forward:!1}},{keys:"",type:"motion",motion:"moveByScroll",motionArgs:{forward:!0,explicitRepeat:!0}},{keys:"",type:"motion",motion:"moveByScroll",motionArgs:{forward:!1,explicitRepeat:!0}},{keys:"gg",type:"motion",motion:"moveToLineOrEdgeOfDocument",motionArgs:{forward:!1,explicitRepeat:!0,linewise:!0,toJumplist:!0}},{keys:"G",type:"motion",motion:"moveToLineOrEdgeOfDocument",motionArgs:{forward:!0,explicitRepeat:!0,linewise:!0,toJumplist:!0}},{keys:"0",type:"motion",motion:"moveToStartOfLine"},{keys:"^",type:"motion",motion:"moveToFirstNonWhiteSpaceCharacter"},{keys:"+",type:"motion",motion:"moveByLines",motionArgs:{forward:!0,toFirstChar:!0}},{keys:"-",type:"motion",motion:"moveByLines",motionArgs:{forward:!1,toFirstChar:!0}},{keys:"_",type:"motion",motion:"moveByLines",motionArgs:{forward:!0,toFirstChar:!0,repeatOffset:-1}},{keys:"$",type:"motion",motion:"moveToEol",motionArgs:{inclusive:!0}},{keys:"%",type:"motion",motion:"moveToMatchedSymbol",motionArgs:{inclusive:!0,toJumplist:!0}},{keys:"f",type:"motion",motion:"moveToCharacter",motionArgs:{forward:!0,inclusive:!0}},{keys:"F",type:"motion",motion:"moveToCharacter",motionArgs:{forward:!1}},{keys:"t",type:"motion",motion:"moveTillCharacter",motionArgs:{forward:!0,inclusive:!0}},{keys:"T",type:"motion",motion:"moveTillCharacter",motionArgs:{forward:!1}},{keys:";",type:"motion",motion:"repeatLastCharacterSearch",motionArgs:{forward:!0}},{keys:",",type:"motion",motion:"repeatLastCharacterSearch",motionArgs:{forward:!1}},{keys:"'",type:"motion",motion:"goToMark",motionArgs:{toJumplist:!0,linewise:!0}},{keys:"`",type:"motion",motion:"goToMark",motionArgs:{toJumplist:!0}},{keys:"]`",type:"motion",motion:"jumpToMark",motionArgs:{forward:!0}},{keys:"[`",type:"motion",motion:"jumpToMark",motionArgs:{forward:!1}},{keys:"]'",type:"motion",motion:"jumpToMark",motionArgs:{forward:!0,linewise:!0}},{keys:"['",type:"motion",motion:"jumpToMark",motionArgs:{forward:!1,linewise:!0}},{keys:"]p",type:"action",action:"paste",isEdit:!0,actionArgs:{after:!0,isEdit:!0,matchIndent:!0}},{keys:"[p",type:"action",action:"paste",isEdit:!0,actionArgs:{after:!1,isEdit:!0,matchIndent:!0}},{keys:"]",type:"motion",motion:"moveToSymbol",motionArgs:{forward:!0,toJumplist:!0}},{keys:"[",type:"motion",motion:"moveToSymbol",motionArgs:{forward:!1,toJumplist:!0}},{keys:"|",type:"motion",motion:"moveToColumn"},{keys:"o",type:"motion",motion:"moveToOtherHighlightedEnd",context:"visual"},{keys:"O",type:"motion",motion:"moveToOtherHighlightedEnd",motionArgs:{sameLine:!0},context:"visual"},{keys:"d",type:"operator",operator:"delete"},{keys:"y",type:"operator",operator:"yank"},{keys:"c",type:"operator",operator:"change"},{keys:">",type:"operator",operator:"indent",operatorArgs:{indentRight:!0}},{keys:"<",type:"operator",operator:"indent",operatorArgs:{indentRight:!1}},{keys:"g~",type:"operator",operator:"changeCase"},{keys:"gu",type:"operator",operator:"changeCase",operatorArgs:{toLower:!0},isEdit:!0},{keys:"gU",type:"operator",operator:"changeCase",operatorArgs:{toLower:!1},isEdit:!0},{keys:"n",type:"motion",motion:"findNext",motionArgs:{forward:!0,toJumplist:!0}},{keys:"N",type:"motion",motion:"findNext",motionArgs:{forward:!1,toJumplist:!0}},{keys:"x",type:"operatorMotion",operator:"delete",motion:"moveByCharacters",motionArgs:{forward:!0},operatorMotionArgs:{visualLine:!1}},{keys:"X",type:"operatorMotion",operator:"delete",motion:"moveByCharacters",motionArgs:{forward:!1},operatorMotionArgs:{visualLine:!0}},{keys:"D",type:"operatorMotion",operator:"delete",motion:"moveToEol",motionArgs:{inclusive:!0},context:"normal"},{keys:"D",type:"operator",operator:"delete",operatorArgs:{linewise:!0},context:"visual"},{keys:"Y",type:"operatorMotion",operator:"yank",motion:"expandToLine",motionArgs:{linewise:!0},context:"normal"},{keys:"Y",type:"operator",operator:"yank",operatorArgs:{linewise:!0},context:"visual"},{keys:"C",type:"operatorMotion",operator:"change",motion:"moveToEol",motionArgs:{inclusive:!0},context:"normal"},{keys:"C",type:"operator",operator:"change",operatorArgs:{linewise:!0},context:"visual"},{keys:"~",type:"operatorMotion",operator:"changeCase",motion:"moveByCharacters",motionArgs:{forward:!0},operatorArgs:{shouldMoveCursor:!0},context:"normal"},{keys:"~",type:"operator",operator:"changeCase",context:"visual"},{keys:"",type:"operatorMotion",operator:"delete",motion:"moveByWords",motionArgs:{forward:!1,wordEnd:!1},context:"insert"},{keys:"",type:"action",action:"jumpListWalk",actionArgs:{forward:!0}},{keys:"",type:"action",action:"jumpListWalk",actionArgs:{forward:!1}},{keys:"",type:"action",action:"scroll",actionArgs:{forward:!0,linewise:!0}},{keys:"",type:"action",action:"scroll",actionArgs:{forward:!1,linewise:!0}},{keys:"a",type:"action",action:"enterInsertMode",isEdit:!0,actionArgs:{insertAt:"charAfter"},context:"normal"},{keys:"A",type:"action",action:"enterInsertMode",isEdit:!0,actionArgs:{insertAt:"eol"},context:"normal"},{keys:"A",type:"action",action:"enterInsertMode",isEdit:!0,actionArgs:{insertAt:"endOfSelectedArea"},context:"visual"},{keys:"i",type:"action",action:"enterInsertMode",isEdit:!0,actionArgs:{insertAt:"inplace"},context:"normal"},{keys:"I",type:"action",action:"enterInsertMode",isEdit:!0,actionArgs:{insertAt:"firstNonBlank"},context:"normal"},{keys:"I",type:"action",action:"enterInsertMode",isEdit:!0,actionArgs:{insertAt:"startOfSelectedArea"},context:"visual"},{keys:"o",type:"action",action:"newLineAndEnterInsertMode",isEdit:!0,interlaceInsertRepeat:!0,actionArgs:{after:!0},context:"normal"},{keys:"O",type:"action",action:"newLineAndEnterInsertMode",isEdit:!0,interlaceInsertRepeat:!0,actionArgs:{after:!1},context:"normal"},{keys:"v",type:"action",action:"toggleVisualMode"},{keys:"V",type:"action",action:"toggleVisualMode",actionArgs:{linewise:!0}},{keys:"",type:"action",action:"toggleVisualMode",actionArgs:{blockwise:!0}},{keys:"",type:"action",action:"toggleVisualMode",actionArgs:{blockwise:!0}},{keys:"gv",type:"action",action:"reselectLastSelection"},{keys:"J",type:"action",action:"joinLines",isEdit:!0},{keys:"p",type:"action",action:"paste",isEdit:!0,actionArgs:{after:!0,isEdit:!0}},{keys:"P",type:"action",action:"paste",isEdit:!0,actionArgs:{after:!1,isEdit:!0}},{keys:"r",type:"action",action:"replace",isEdit:!0},{keys:"@",type:"action",action:"replayMacro"},{keys:"q",type:"action",action:"enterMacroRecordMode"},{keys:"R",type:"action",action:"enterInsertMode",isEdit:!0,actionArgs:{replace:!0}},{keys:"u",type:"action",action:"undo",context:"normal"},{keys:"u",type:"operator",operator:"changeCase",operatorArgs:{toLower:!0},context:"visual",isEdit:!0},{keys:"U",type:"operator",operator:"changeCase",operatorArgs:{toLower:!1},context:"visual",isEdit:!0},{keys:"",type:"action",action:"redo"},{keys:"m",type:"action",action:"setMark"},{keys:'"',type:"action",action:"setRegister"},{keys:"zz",type:"action",action:"scrollToCursor",actionArgs:{position:"center"}},{keys:"z.",type:"action",action:"scrollToCursor",actionArgs:{position:"center"},motion:"moveToFirstNonWhiteSpaceCharacter"},{keys:"zt",type:"action",action:"scrollToCursor",actionArgs:{position:"top"}},{keys:"z",type:"action",action:"scrollToCursor",actionArgs:{position:"top"},motion:"moveToFirstNonWhiteSpaceCharacter"},{keys:"z-",type:"action",action:"scrollToCursor",actionArgs:{position:"bottom"}},{keys:"zb",type:"action",action:"scrollToCursor",actionArgs:{position:"bottom"},motion:"moveToFirstNonWhiteSpaceCharacter"},{keys:".",type:"action",action:"repeatLastEdit"},{keys:"",type:"action",action:"incrementNumberToken",isEdit:!0,actionArgs:{increase:!0,backtrack:!1}},{keys:"",type:"action",action:"incrementNumberToken",isEdit:!0,actionArgs:{increase:!1,backtrack:!1}},{keys:"",type:"action",action:"indent",actionArgs:{indentRight:!0},context:"insert"},{keys:"",type:"action",action:"indent",actionArgs:{indentRight:!1},context:"insert"},{keys:"a",type:"motion",motion:"textObjectManipulation"},{keys:"i",type:"motion",motion:"textObjectManipulation",motionArgs:{textObjectInner:!0}},{keys:"/",type:"search",searchArgs:{forward:!0,querySrc:"prompt",toJumplist:!0}},{keys:"?",type:"search",searchArgs:{forward:!1,querySrc:"prompt",toJumplist:!0}},{keys:"*",type:"search",searchArgs:{forward:!0,querySrc:"wordUnderCursor",wholeWordOnly:!0,toJumplist:!0}},{keys:"#",type:"search",searchArgs:{forward:!1,querySrc:"wordUnderCursor",wholeWordOnly:!0,toJumplist:!0}},{keys:"g*",type:"search",searchArgs:{forward:!0,querySrc:"wordUnderCursor",toJumplist:!0}},{keys:"g#",type:"search",searchArgs:{forward:!1,querySrc:"wordUnderCursor",toJumplist:!0}},{keys:":",type:"ex"}],n=[{name:"colorscheme",shortName:"colo"},{name:"map"},{name:"imap",shortName:"im"},{name:"nmap",shortName:"nm"},{name:"vmap",shortName:"vm"},{name:"unmap"},{name:"write",shortName:"w"},{name:"undo",shortName:"u"},{name:"redo",shortName:"red"},{name:"set",shortName:"se"},{name:"set",shortName:"se"},{name:"setlocal",shortName:"setl"},{name:"setglobal",shortName:"setg"},{name:"sort",shortName:"sor"},{name:"substitute",shortName:"s",possiblyAsync:!0},{name:"nohlsearch",shortName:"noh"},{name:"yank",shortName:"y"},{name:"delmarks",shortName:"delm"},{name:"registers",shortName:"reg",excludeFromCommandHistory:!0},{name:"global",shortName:"g"}],r=e.Pos;e.Vim=function(){function i(t,n){this==e.keyMap.vim&&(e.rmClass(t.getWrapperElement(),"cm-fat-cursor"),"contenteditable"==t.getOption("inputStyle")&&null!=document.body.style.caretColor&&(function(e){var t=e.state.fatCursorMarks;if(t)for(var n=0;n")}(t);if(!r)return!1;var i=e.Vim.findKey(n,r);return"function"==typeof i&&e.signal(n,"vim-keypress",r),i}}e.defineOption("vimMode",!1,function(t,n,r){n&&"vim"!=t.getOption("keyMap")?t.setOption("keyMap","vim"):!n&&r!=e.Init&&/^vim/.test(t.getOption("keyMap"))&&t.setOption("keyMap","default")});var c={Shift:"S",Ctrl:"C",Alt:"A",Cmd:"D",Mod:"A"},u={Enter:"CR",Backspace:"BS",Delete:"Del",Insert:"Ins"};function f(e){var t=e.state.vim;return t.onPasteFn||(t.onPasteFn=function(){t.insertMode||(e.setCursor(Q(e.getCursor(),0,1)),Y.enterInsertMode(e,{},t))}),t.onPasteFn}var d=/[\d]/,h=[e.isWordChar,function(t){return t&&!e.isWordChar(t)&&!/\s/.test(t)}],p=[function(e){return/\S/.test(e)}];function m(e,t){for(var n=[],r=e;r"]),x=[].concat(g,v,y,["-",'"',".",":","/"]);function w(e,t){return t>=e.firstLine()&&t<=e.lastLine()}function k(e){return/^[a-z]$/.test(e)}function C(e){return-1!="()[]{}".indexOf(e)}function S(e){return d.test(e)}function L(e){return/^[A-Z]$/.test(e)}function M(e){return/^\s*$/.test(e)}function T(e){return-1!=".?!".indexOf(e)}function A(e,t){for(var n=0;nn?t=n:t0?1:-1,u=o.getCursor();do{if((l=i[(e+(t+=c))%e])&&(s=l.find())&&!re(u,s))break}while(tr)}return l}}},D=function(e){return e?{changes:e.changes,expectCursorActivityForChange:e.expectCursorActivityForChange}:{changes:[],expectCursorActivityForChange:!1}};function F(){this.latestRegister=void 0,this.isPlaying=!1,this.isRecording=!1,this.replaySearchQueries=[],this.onRecordingDone=void 0,this.lastInsertModeChanges=D()}function z(e){return e.state.vim||(e.state.vim={inputState:new H,lastEditInputState:void 0,lastEditActionCommand:void 0,lastHPos:-1,lastHSPos:-1,lastMotion:null,marks:{},fakeCursor:null,insertMode:!1,insertModeRepeat:void 0,visualMode:!1,visualLine:!1,visualBlock:!1,lastSelection:null,lastPastedText:null,sel:{},options:{}}),e.state.vim}function W(){for(var e in I={searchQuery:null,searchIsReversed:!1,lastSubstituteReplacePart:void 0,jumpList:B(),macroModeState:new F,lastCharacterSearch:{increment:0,forward:!0,selectedCharacter:""},registerController:new U({}),searchHistoryController:new V,exCommandHistoryController:new V},O){var t=O[e];t.value=t.defaultValue}}F.prototype={exitMacroRecordMode:function(){var e=I.macroModeState;e.onRecordingDone&&e.onRecordingDone(),e.onRecordingDone=void 0,e.isRecording=!1},enterMacroRecordMode:function(e,t){var n=I.registerController.getRegister(t);n&&(n.clear(),this.latestRegister=t,e.openDialog&&(this.onRecordingDone=e.openDialog("(recording)["+t+"]",null,{bottom:!0})),this.isRecording=!0)}};var _={buildKeyMap:function(){},getRegisterController:function(){return I.registerController},resetVimGlobalState_:W,getVimGlobalState_:function(){return I},maybeInitVimState_:z,suppressErrorLogging:!1,InsertModeKey:tt,map:function(e,t,n){Ge.map(e,t,n)},unmap:function(e,t){Ge.unmap(e,t)},setOption:N,getOption:P,defineOption:E,defineEx:function(e,t,n){if(t){if(0!==e.indexOf(t))throw new Error('(Vim.defineEx) "'+t+'" is not a prefix of "'+e+'", command not registered')}else t=e;$e[e]=n,Ge.commandMap_[t]={name:e,shortName:t,type:"api"}},handleKey:function(e,t,n){var r=this.findKey(e,t,n);if("function"==typeof r)return r()},findKey:function(n,r,i){var o,a=z(n);function l(){var e=I.macroModeState;if(e.isRecording){if("q"==r)return e.exitMacroRecordMode(),K(n),!0;"mapping"!=i&&function(e,t){if(!e.isPlaying){var n=e.latestRegister,r=I.registerController.getRegister(n);r&&r.pushText(t)}}(e,r)}}function s(){if(""==r)return K(n),a.visualMode?ge(n):a.insertMode&&Xe(n),!0}return!1===(o=a.insertMode?function(){if(s())return!0;for(var e=a.inputState.keyBuffer=a.inputState.keyBuffer+r,i=1==r.length,o=q.matchCommand(e,t,a.inputState,"insert");e.length>1&&"full"!=o.type;){var e=a.inputState.keyBuffer=e.slice(1),l=q.matchCommand(e,t,a.inputState,"insert");"none"!=l.type&&(o=l)}if("none"==o.type)return K(n),!1;if("partial"==o.type)return R&&window.clearTimeout(R),R=window.setTimeout(function(){a.insertMode&&a.inputState.keyBuffer&&K(n)},P("insertModeEscKeysTimeout")),!i;if(R&&window.clearTimeout(R),i){for(var c=n.listSelections(),u=0;u|<\w+>|./.exec(t),r=i[0],t=t.substring(i.index+r.length),e.Vim.handleKey(n,r,"mapping")}(o.toKeys):q.processCommand(n,a,o)}catch(t){throw n.state.vim=void 0,z(n),e.Vim.suppressErrorLogging||console.log(t),t}return!0})}},handleEx:function(e,t){Ge.processCommand(e,t)},defineMotion:function(e,t){$[e]=t},defineAction:function(e,t){Y[e]=t},defineOperator:function(e,t){X[e]=t},mapCommand:function(e,t,n,r,i){var o={keys:e,type:t};for(var a in o[t]=n,o[t+"Args"]=r,i)o[a]=i[a];Ye(o)},_mapCommand:Ye,defineRegister:function(e,t){var n=I.registerController.registers;if(!e||1!=e.length)throw Error("Register name must be 1 character");if(n[e])throw Error("Register already defined "+e);n[e]=t,x.push(e)},exitVisualMode:ge,exitInsertMode:Xe};function H(){this.prefixRepeat=[],this.motionRepeat=[],this.operator=null,this.operatorArgs=null,this.motion=null,this.motionArgs=null,this.keyBuffer=[],this.registerName=null}function K(t,n){t.state.vim.inputState=new H,e.signal(t,"vim-command-done",n)}function j(e,t,n){this.clear(),this.keyBuffer=[e||""],this.insertModeChanges=[],this.searchQueries=[],this.linewise=!!t,this.blockwise=!!n}function U(e){this.registers=e,this.unnamedRegister=e['"']=new j,e["."]=new j,e[":"]=new j,e["/"]=new j}function V(){this.historyBuffer=[],this.iterator=0,this.initialPrefix=null}H.prototype.pushRepeatDigit=function(e){this.operator?this.motionRepeat=this.motionRepeat.concat(e):this.prefixRepeat=this.prefixRepeat.concat(e)},H.prototype.getRepeat=function(){var e=0;return(this.prefixRepeat.length>0||this.motionRepeat.length>0)&&(e=1,this.prefixRepeat.length>0&&(e*=parseInt(this.prefixRepeat.join(""),10)),this.motionRepeat.length>0&&(e*=parseInt(this.motionRepeat.join(""),10))),e},j.prototype={setText:function(e,t,n){this.keyBuffer=[e||""],this.linewise=!!t,this.blockwise=!!n},pushText:function(e,t){t&&(this.linewise||this.keyBuffer.push("\n"),this.linewise=!0),this.keyBuffer.push(e)},pushInsertModeChanges:function(e){this.insertModeChanges.push(D(e))},pushSearchQuery:function(e){this.searchQueries.push(e)},clear:function(){this.keyBuffer=[],this.insertModeChanges=[],this.searchQueries=[],this.linewise=!1},toString:function(){return this.keyBuffer.join("")}},U.prototype={pushText:function(e,t,n,r,i){r&&"\n"!==n.charAt(n.length-1)&&(n+="\n");var o=this.isValidRegister(e)?this.getRegister(e):null;if(o){var a=L(e);a?o.pushText(n,r):o.setText(n,r,i),this.unnamedRegister.setText(o.toString(),r)}else{switch(t){case"yank":this.registers[0]=new j(n,r,i);break;case"delete":case"change":-1==n.indexOf("\n")?this.registers["-"]=new j(n,r):(this.shiftNumericRegisters_(),this.registers[1]=new j(n,r))}this.unnamedRegister.setText(n,r,i)}},getRegister:function(e){return this.isValidRegister(e)?(e=e.toLowerCase(),this.registers[e]||(this.registers[e]=new j),this.registers[e]):this.unnamedRegister},isValidRegister:function(e){return e&&A(e,x)},shiftNumericRegisters_:function(){for(var e=9;e>=2;e--)this.registers[e]=this.getRegister(""+(e-1))}},V.prototype={nextMatch:function(e,t){var n=this.historyBuffer,r=t?-1:1;null===this.initialPrefix&&(this.initialPrefix=e);for(var i=this.iterator+r;t?i>=0:i=n.length?(this.iterator=n.length,this.initialPrefix):i<0?e:void 0},pushInput:function(e){var t=this.historyBuffer.indexOf(e);t>-1&&this.historyBuffer.splice(t,1),e.length&&this.historyBuffer.push(e)},reset:function(){this.initialPrefix=null,this.iterator=this.historyBuffer.length}};var q={matchCommand:function(e,t,n,r){var i,o=function(e,t,n,r){for(var i,o=[],a=[],l=0;l"==i.keys.slice(-11)){var s=function(e){var t=/^.*(<[^>]+>)$/.exec(e),n=t?t[1]:e.slice(-1);if(n.length>1)switch(n){case"":n="\n";break;case"":n=" ";break;default:n=""}return n}(e);if(!s)return{type:"none"};n.selectedCharacter=s}return{type:"full",command:i}},processCommand:function(e,t,n){switch(t.inputState.repeatOverride=n.repeatOverride,n.type){case"motion":this.processMotion(e,t,n);break;case"operator":this.processOperator(e,t,n);break;case"operatorMotion":this.processOperatorMotion(e,t,n);break;case"action":this.processAction(e,t,n);break;case"search":this.processSearch(e,t,n);break;case"ex":case"keyToEx":this.processEx(e,t,n)}},processMotion:function(e,t,n){t.inputState.motion=n.motion,t.inputState.motionArgs=J(n.motionArgs),this.evalInput(e,t)},processOperator:function(e,t,n){var r=t.inputState;if(r.operator){if(r.operator==n.operator)return r.motion="expandToLine",r.motionArgs={linewise:!0},void this.evalInput(e,t);K(e)}r.operator=n.operator,r.operatorArgs=J(n.operatorArgs),t.visualMode&&this.evalInput(e,t)},processOperatorMotion:function(e,t,n){var r=t.visualMode,i=J(n.operatorMotionArgs);i&&r&&i.visualLine&&(t.visualLine=!0),this.processOperator(e,t,n),r||this.processMotion(e,t,n)},processAction:function(e,t,n){var r=t.inputState,i=r.getRepeat(),o=!!i,a=J(n.actionArgs)||{};r.selectedCharacter&&(a.selectedCharacter=r.selectedCharacter),n.operator&&this.processOperator(e,t,n),n.motion&&this.processMotion(e,t,n),(n.motion||n.operator)&&this.evalInput(e,t),a.repeat=i||1,a.repeatIsExplicit=o,a.registerName=r.registerName,K(e),t.lastMotion=null,n.isEdit&&this.recordLastEdit(t,r,n),Y[n.action](e,a,t)},processSearch:function(t,n,r){if(t.getSearchCursor){var i=r.searchArgs.forward,o=r.searchArgs.wholeWordOnly;Oe(t).setReversed(!i);var a=i?"/":"?",l=Oe(t).getQuery(),s=t.getScrollInfo();switch(r.searchArgs.querySrc){case"prompt":var c=I.macroModeState;if(c.isPlaying){var u=c.replaySearchQueries.shift();h(u,!0,!1)}else ze(t,{onClose:function(e){t.scrollTo(s.left,s.top),h(e,!0,!0);var n=I.macroModeState;n.isRecording&&function(e,t){if(!e.isPlaying){var n=e.latestRegister,r=I.registerController.getRegister(n);r&&r.pushSearchQuery&&r.pushSearchQuery(t)}}(n,e)},prefix:a,desc:Fe,onKeyUp:function(n,r,o){var a,l,c,u=e.keyName(n);"Up"==u||"Down"==u?(a="Up"==u,l=n.target?n.target.selectionEnd:0,r=I.searchHistoryController.nextMatch(r,a)||"",o(r),l&&n.target&&(n.target.selectionEnd=n.target.selectionStart=Math.min(l,n.target.value.length))):"Left"!=u&&"Right"!=u&&"Ctrl"!=u&&"Alt"!=u&&"Shift"!=u&&I.searchHistoryController.reset();try{c=We(t,r,!0,!0)}catch(n){}c?t.scrollIntoView(He(t,!i,c),30):(Ke(t),t.scrollTo(s.left,s.top))},onKeyDown:function(n,r,i){var o=e.keyName(n);"Esc"==o||"Ctrl-C"==o||"Ctrl-["==o||"Backspace"==o&&""==r?(I.searchHistoryController.pushInput(r),I.searchHistoryController.reset(),We(t,l),Ke(t),t.scrollTo(s.left,s.top),e.e_stop(n),K(t),i(),t.focus()):"Up"==o||"Down"==o?e.e_stop(n):"Ctrl-U"==o&&(e.e_stop(n),i(""))}});break;case"wordUnderCursor":var f=ye(t,!1,0,!1,!0),d=!0;if(f||(f=ye(t,!1,0,!1,!1),d=!1),!f)return;var u=t.getLine(f.start.line).substring(f.start.ch,f.end.ch);u=d&&o?"\\b"+u+"\\b":function(e){return e.replace(/([.?*+$\[\]\/\\(){}|\-])/g,"\\$1")}(u),I.jumpList.cachedCursor=t.getCursor(),t.setCursor(f.start),h(u,!0,!1)}}function h(e,i,o){I.searchHistoryController.pushInput(e),I.searchHistoryController.reset();try{We(t,e,i,o)}catch(n){return De(t,"Invalid regex: "+e),void K(t)}q.processMotion(t,n,{type:"motion",motion:"findNext",motionArgs:{forward:!0,toJumplist:r.searchArgs.toJumplist}})}},processEx:function(t,n,r){function i(e){I.exCommandHistoryController.pushInput(e),I.exCommandHistoryController.reset(),Ge.processCommand(t,e)}function o(n,r,i){var o,a,l=e.keyName(n);("Esc"==l||"Ctrl-C"==l||"Ctrl-["==l||"Backspace"==l&&""==r)&&(I.exCommandHistoryController.pushInput(r),I.exCommandHistoryController.reset(),e.e_stop(n),K(t),i(),t.focus()),"Up"==l||"Down"==l?(e.e_stop(n),o="Up"==l,a=n.target?n.target.selectionEnd:0,r=I.exCommandHistoryController.nextMatch(r,o)||"",i(r),a&&n.target&&(n.target.selectionEnd=n.target.selectionStart=Math.min(a,n.target.value.length))):"Ctrl-U"==l?(e.e_stop(n),i("")):"Left"!=l&&"Right"!=l&&"Ctrl"!=l&&"Alt"!=l&&"Shift"!=l&&I.exCommandHistoryController.reset()}"keyToEx"==r.type?Ge.processCommand(t,r.exArgs.input):n.visualMode?ze(t,{onClose:i,prefix:":",value:"'<,'>",onKeyDown:o,selectValueOnOpen:!1}):ze(t,{onClose:i,prefix:":",onKeyDown:o})},evalInput:function(e,t){var n,i,o,a=t.inputState,l=a.motion,s=a.motionArgs||{},c=a.operator,u=a.operatorArgs||{},f=a.registerName,d=t.sel,h=ne(t.visualMode?Z(e,d.head):e.getCursor("head")),p=ne(t.visualMode?Z(e,d.anchor):e.getCursor("anchor")),m=ne(h),g=ne(p);if(c&&this.recordLastEdit(t,a),(o=void 0!==a.repeatOverride?a.repeatOverride:a.getRepeat())>0&&s.explicitRepeat?s.repeatIsExplicit=!0:(s.noRepeat||!s.explicitRepeat&&0===o)&&(o=1,s.repeatIsExplicit=!1),a.selectedCharacter&&(s.selectedCharacter=u.selectedCharacter=a.selectedCharacter),s.repeat=o,K(e),l){var v=$[l](e,h,s,t);if(t.lastMotion=$[l],!v)return;if(s.toJumplist){var y=I.jumpList,b=y.cachedCursor;b?(be(e,b,v),delete y.cachedCursor):be(e,h,v)}v instanceof Array?(i=v[0],n=v[1]):n=v,n||(n=ne(h)),t.visualMode?(t.visualBlock&&n.ch===1/0||(n=Z(e,n,t.visualBlock)),i&&(i=Z(e,i,!0)),i=i||g,d.anchor=i,d.head=n,pe(e),Le(e,t,"<",ie(i,n)?i:n),Le(e,t,">",ie(i,n)?n:i)):c||(n=Z(e,n),e.setCursor(n.line,n.ch))}if(c){if(u.lastSel){i=g;var x=u.lastSel,w=Math.abs(x.head.line-x.anchor.line),k=Math.abs(x.head.ch-x.anchor.ch);n=x.visualLine?r(g.line+w,g.ch):x.visualBlock?r(g.line+w,g.ch+k):x.head.line==x.anchor.line?r(g.line,g.ch+k):r(g.line+w,g.ch),t.visualMode=!0,t.visualLine=x.visualLine,t.visualBlock=x.visualBlock,d=t.sel={anchor:i,head:n},pe(e)}else t.visualMode&&(u.lastSel={anchor:ne(d.anchor),head:ne(d.head),visualBlock:t.visualBlock,visualLine:t.visualLine});var C,S,L,T,A;if(t.visualMode){if(C=oe(d.head,d.anchor),S=ae(d.head,d.anchor),L=t.visualLine||u.linewise,T=t.visualBlock?"block":L?"line":"char",A=me(e,{anchor:C,head:S},T),L){var O=A.ranges;if("block"==T)for(var E=0;E0&&o&&M(o);o=i.pop())n.line--,n.ch=0;o?(n.line--,n.ch=se(e,n.line)):n.ch=0}}(e,C,S),T="char";var P=!s.inclusive||L;A=me(e,{anchor:C,head:S},T,P)}e.setSelections(A.ranges,A.primary),t.lastMotion=null,u.repeat=o,u.registerName=f,u.linewise=L;var R=X[c](e,u,A.ranges,g,n);t.visualMode&&ge(e,null!=R),R&&e.setCursor(R)}},recordLastEdit:function(e,t,n){var r=I.macroModeState;r.isPlaying||(e.lastEditInputState=t,e.lastEditActionCommand=n,r.lastInsertModeChanges.changes=[],r.lastInsertModeChanges.expectCursorActivityForChange=!1)}},$={moveToTopLine:function(e,t,n){var i=Ue(e).top+n.repeat-1;return r(i,ve(e.getLine(i)))},moveToMiddleLine:function(e){var t=Ue(e),n=Math.floor(.5*(t.top+t.bottom));return r(n,ve(e.getLine(n)))},moveToBottomLine:function(e,t,n){var i=Ue(e).bottom-n.repeat+1;return r(i,ve(e.getLine(i)))},expandToLine:function(e,t,n){var i=t;return r(i.line+n.repeat-1,1/0)},findNext:function(e,t,n){var r=Oe(e),i=r.getQuery();if(i){var o=!n.forward;return o=r.isReversed()?!o:o,_e(e,i),He(e,o,i,n.repeat)}},goToMark:function(e,t,n,r){var i=Ve(e,r,n.selectedCharacter);return i?n.linewise?{line:i.line,ch:ve(e.getLine(i.line))}:i:null},moveToOtherHighlightedEnd:function(e,t,n,i){if(i.visualBlock&&n.sameLine){var o=i.sel;return[Z(e,r(o.anchor.line,o.head.ch)),Z(e,r(o.head.line,o.anchor.ch))]}return[i.sel.head,i.sel.anchor]},jumpToMark:function(e,t,n,i){for(var o=t,a=0;au&&o.line==u?this.moveToEol(e,t,n,i):(n.toFirstChar&&(a=ve(e.getLine(s)),i.lastHPos=a),i.lastHSPos=e.charCoords(r(s,a),"div").left,r(s,a))},moveByDisplayLines:function(e,t,n,i){var o=t;switch(i.lastMotion){case this.moveByDisplayLines:case this.moveByScroll:case this.moveByLines:case this.moveToColumn:case this.moveToEol:break;default:i.lastHSPos=e.charCoords(o,"div").left}var a=n.repeat,l=e.findPosV(o,n.forward?a:-a,"line",i.lastHSPos);if(l.hitSide)if(n.forward)var s=e.charCoords(l,"div"),c={top:s.top+8,left:i.lastHSPos},l=e.coordsChar(c,"div");else{var u=e.charCoords(r(e.firstLine(),0),"div");u.left=i.lastHSPos,l=e.coordsChar(u,"div")}return i.lastHPos=l.ch,l},moveByPage:function(e,t,n){var r=t,i=n.repeat;return e.findPosV(r,n.forward?i:-i,"page")},moveByParagraph:function(e,t,n){var r=n.forward?1:-1;return Te(e,t,n.repeat,r)},moveBySentence:function(e,t,n){var i=n.forward?1:-1;return function(e,t,n,i){function o(e,t){if(t.pos+t.dir<0||t.pos+t.dir>=t.line.length){if(t.ln+=t.dir,!w(e,t.ln))return t.line=null,t.ln=null,void(t.pos=null);t.line=e.getLine(t.ln),t.pos=t.dir>0?0:t.line.length-1}else t.pos+=t.dir}function a(e,t,n,r){var i=e.getLine(t),a=""===i,l={line:i,ln:t,pos:n,dir:r},s={ln:l.ln,pos:l.pos},c=""===l.line;for(o(e,l);null!==l.line;){if(s.ln=l.ln,s.pos=l.pos,""===l.line&&!c)return{ln:l.ln,pos:l.pos};if(a&&""!==l.line&&!M(l.line[l.pos]))return{ln:l.ln,pos:l.pos};!T(l.line[l.pos])||a||l.pos!==l.line.length-1&&!M(l.line[l.pos+1])||(a=!0),o(e,l)}var i=e.getLine(s.ln);s.pos=0;for(var u=i.length-1;u>=0;--u)if(!M(i[u])){s.pos=u;break}return s}function l(e,t,n,r){var i=e.getLine(t),a={line:i,ln:t,pos:n,dir:r},l={ln:a.ln,pos:null},s=""===a.line;for(o(e,a);null!==a.line;){if(""===a.line&&!s)return null!==l.pos?l:{ln:a.ln,pos:a.pos};if(T(a.line[a.pos])&&null!==l.pos&&(a.ln!==l.ln||a.pos+1!==l.pos))return l;""===a.line||M(a.line[a.pos])||(s=!1,l={ln:a.ln,pos:a.pos}),o(e,a)}var i=e.getLine(l.ln);l.pos=0;for(var c=0;c0;)s=i<0?l(e,s.ln,s.pos,i):a(e,s.ln,s.pos,i),n--;return r(s.ln,s.pos)}(e,t,n.repeat,i)},moveByScroll:function(e,t,n,r){var i=e.getScrollInfo(),o=null,a=n.repeat;a||(a=i.clientHeight/(2*e.defaultTextHeight()));var l=e.charCoords(t,"local");n.repeat=a;var o=$.moveByDisplayLines(e,t,n,r);if(!o)return null;var s=e.charCoords(o,"local");return e.scrollTo(null,i.top+s.top-l.top),o},moveByWords:function(e,t,n){return function(e,t,n,i,o,a){var l=ne(t),s=[];(i&&!o||!i&&o)&&n++;for(var c=!(i&&o),u=0;u0)f.index=0;else{var m=f.lineText.length;f.index=m>0?m-1:0}f.nextCh=f.lineText.charAt(f.index)}p(f)&&(o.line=c,o.ch=f.index,t--)}return f.nextCh||f.curMoveThrough?r(c,f.index):o}(e,i,n.forward,n.selectedCharacter)||t},moveToColumn:function(e,t,n,i){var o=n.repeat;return i.lastHPos=o-1,i.lastHSPos=e.charCoords(t,"div").left,function(e,t){var n=e.getCursor().line;return Z(e,r(n,t-1))}(e,o)},moveToEol:function(e,t,n,i){var o=t;i.lastHPos=1/0;var a=r(o.line+n.repeat-1,1/0),l=e.clipPos(a);return l.ch--,i.lastHSPos=e.charCoords(l,"div").left,a},moveToFirstNonWhiteSpaceCharacter:function(e,t){var n=t;return r(n.line,ve(e.getLine(n.line)))},moveToMatchedSymbol:function(e,t){for(var n,i=t,o=i.line,a=i.ch,l=e.getLine(o);aa.ch||o.line>a.line){var f=o;o=a,a=f}return i?a.ch+=1:o.ch+=1,{start:o,end:a}}(e,t,o,l);else if({"'":!0,'"':!0}[o])a=function(e,t,n,i){var o,a,l,s,c=ne(t),u=e.getLine(c.line).split(""),f=u.indexOf(n);if(c.ch-1&&!o;l--)u[l]==n&&(o=l+1);else o=c.ch+1;if(o&&!a)for(l=o,s=u.length;lt.lastLine()&&n.linewise&&!p?t.replaceRange("",h,u):t.replaceRange("",c,u),n.linewise&&(p||(t.setCursor(h),e.commands.newlineAndIndent(t)),c.ch=Number.MAX_VALUE),o=c}I.registerController.pushText(n.registerName,"change",a,n.linewise,i.length>1),Y.enterInsertMode(t,{head:o},t.state.vim)},delete:function(e,t,n){var i,o,a=e.state.vim;if(a.visualBlock){o=e.getSelection();var l=G("",n.length);e.replaceSelections(l),i=n[0].anchor}else{var s=n[0].anchor,c=n[0].head;t.linewise&&c.line!=e.firstLine()&&s.line==e.lastLine()&&s.line==c.line-1&&(s.line==e.firstLine()?s.ch=0:s=r(s.line-1,se(e,s.line-1))),o=e.getRange(s,c),e.replaceRange("",s,c),i=s,t.linewise&&(i=$.moveToFirstNonWhiteSpaceCharacter(e,s))}I.registerController.pushText(t.registerName,"delete",o,t.linewise,a.visualBlock);var u=a.insertMode;return Z(e,i,u)},indent:function(e,t,n){var r=e.state.vim,i=n[0].anchor.line,o=r.visualBlock?n[n.length-1].anchor.line:n[0].head.line,a=r.visualMode?t.repeat:1;t.linewise&&o--;for(var l=i;l<=o;l++)for(var s=0;sc.top?(s.line+=(l-c.top)/i,s.line=Math.ceil(s.line),e.setCursor(s),c=e.charCoords(s,"local"),e.scrollTo(null,c.top)):e.scrollTo(null,l);else{var u=l+e.getScrollInfo().clientHeight;u=a.anchor.line?Q(a.head,0,1):r(a.anchor.line,0);else if("inplace"==o&&i.visualMode)return;t.setOption("disableInput",!1),n&&n.replace?(t.toggleOverwrite(!0),t.setOption("keyMap","vim-replace"),e.signal(t,"vim-mode-change",{mode:"replace"})):(t.toggleOverwrite(!1),t.setOption("keyMap","vim-insert"),e.signal(t,"vim-mode-change",{mode:"insert"})),I.macroModeState.isPlaying||(t.on("change",Je),e.on(t.getInputField(),"keydown",nt)),i.visualMode&&ge(t),de(t,l,s)}},toggleVisualMode:function(t,n,i){var o,a=n.repeat,l=t.getCursor();i.visualMode?i.visualLine^n.linewise||i.visualBlock^n.blockwise?(i.visualLine=!!n.linewise,i.visualBlock=!!n.blockwise,e.signal(t,"vim-mode-change",{mode:"visual",subMode:i.visualLine?"linewise":i.visualBlock?"blockwise":""}),pe(t)):ge(t):(i.visualMode=!0,i.visualLine=!!n.linewise,i.visualBlock=!!n.blockwise,o=Z(t,r(l.line,l.ch+a-1),!0),i.sel={anchor:l,head:o},e.signal(t,"vim-mode-change",{mode:"visual",subMode:i.visualLine?"linewise":i.visualBlock?"blockwise":""}),pe(t),Le(t,i,"<",oe(l,o)),Le(t,i,">",ae(l,o)))},reselectLastSelection:function(t,n,r){var i=r.lastSelection;if(r.visualMode&&he(t,r),i){var o=i.anchorMark.find(),a=i.headMark.find();if(!o||!a)return;r.sel={anchor:o,head:a},r.visualMode=!0,r.visualLine=i.visualLine,r.visualBlock=i.visualBlock,pe(t),Le(t,r,"<",oe(o,a)),Le(t,r,">",ae(o,a)),e.signal(t,"vim-mode-change",{mode:"visual",subMode:r.visualLine?"linewise":r.visualBlock?"blockwise":""})}},joinLines:function(e,t,n){var i,o;if(n.visualMode){if(i=e.getCursor("anchor"),ie(o=e.getCursor("head"),i)){var a=o;o=i,i=a}o.ch=se(e,o.line)-1}else{var l=Math.max(t.repeat,2);i=e.getCursor(),o=Z(e,r(i.line+l-1,1/0))}for(var s=0,c=i.line;c1)var a=Array(t.repeat+1).join(a);var p,m,g=o.linewise,v=o.blockwise;if(g)n.visualMode?a=n.visualLine?a.slice(0,-1):"\n"+a.slice(0,a.length-1)+"\n":t.after?(a="\n"+a.slice(0,a.length-1),i.ch=se(e,i.line)):i.ch=0;else{if(v){a=a.split("\n");for(var y=0;ye.lastLine()&&e.replaceRange("\n",r(M,0));var T=se(e,M);Tu.length&&(o=u.length),a=r(s.line,o)}if("\n"==l)i.visualMode||t.replaceRange("",s,a),(e.commands.newlineAndIndentContinueComment||e.commands.newlineAndIndent)(t);else{var f=t.getRange(s,a);if(f=f.replace(/[^\n]/g,l),i.visualBlock){var d=new Array(t.getOption("tabSize")+1).join(" ");f=(f=t.getSelection()).replace(/\t/g,d).replace(/[^\n]/g,l).split("\n"),t.replaceSelections(f)}else t.replaceRange(f,s,a);i.visualMode?(s=ie(c[0].anchor,c[0].head)?c[0].anchor:c[0].head,t.setCursor(s),ge(t,!1)):t.setCursor(Q(a,0,-1))}},incrementNumberToken:function(e,t){for(var n,i,o,a,l=e.getCursor(),s=e.getLine(l.line),c=/(-?)(?:(0x)([\da-f]+)|(0b|0|)(\d+))/gi;null!==(n=c.exec(s))&&(i=n.index,o=i+n[0].length,!(l.ch"==t.slice(-11)){var n=t.length-11,r=e.slice(0,n),i=t.slice(0,n);return r==i&&e.length>n?"full":0==i.indexOf(r)&&"partial"}return e==t?"full":0==t.indexOf(e)&&"partial"}function te(e,t,n){return function(){for(var r=0;r2&&(t=oe.apply(void 0,Array.prototype.slice.call(arguments,1))),ie(e,t)?e:t}function ae(e,t){return arguments.length>2&&(t=ae.apply(void 0,Array.prototype.slice.call(arguments,1))),ie(e,t)?t:e}function le(e,t,n){var r=ie(e,t),i=ie(t,n);return r&&i}function se(e,t){return e.getLine(t).length}function ce(e){return e.trim?e.trim():e.replace(/^\s+|\s+$/g,"")}function ue(e,t,n){var i=se(e,t),o=new Array(n-i+1).join(" ");e.setCursor(r(t,i)),e.replaceRange(o,e.getCursor())}function fe(e,t){var n=[],i=e.listSelections(),o=ne(e.clipPos(t)),a=!re(t,o),l=e.getCursor("head"),s=function(e,t,n){for(var r=0;rs?u:0,d=i[f].anchor,h=Math.min(d.line,o.line),p=Math.max(d.line,o.line),m=d.ch,g=o.ch,v=i[f].head.ch-m,y=g-m;v>0&&y<=0?(m++,a||g--):v<0&&y>=0?(m--,c||g++):v<0&&-1==y&&(m--,g++);for(var b=h;b<=p;b++){var x={anchor:new r(b,m),head:new r(b,g)};n.push(x)}return e.setSelections(n),t.ch=g,d.ch=m,d}function de(e,t,n){for(var r=[],i=0;ic&&(o.line=c),o.ch=se(e,o.line)}return{ranges:[{anchor:a,head:o}],primary:0}}if("block"==n){for(var u=Math.min(a.line,o.line),f=Math.min(a.ch,o.ch),d=Math.max(a.line,o.line),h=Math.max(a.ch,o.ch)+1,p=d-u+1,m=o.line==u?0:p-1,g=[],v=0;v=l.length)return null;i?c=p[0]:(c=h[0])(l.charAt(s))||(c=h[1]);for(var u=s,f=s;c(l.charAt(u))&&u=0;)f--;if(f++,t){for(var d=u;/\s/.test(l.charAt(u))&&u0;)f--;f||(f=m)}}return{start:r(a.line,f),end:r(a.line,u)}}function be(e,t,n){re(t,n)||I.jumpList.add(e,t,n)}function xe(e,t){I.lastCharacterSearch.increment=e,I.lastCharacterSearch.forward=t.forward,I.lastCharacterSearch.selectedCharacter=t.selectedCharacter}var we={"(":"bracket",")":"bracket","{":"bracket","}":"bracket","[":"section","]":"section","*":"comment","/":"comment",m:"method",M:"method","#":"preprocess"},ke={bracket:{isComplete:function(e){if(e.nextCh===e.symb){if(e.depth++,e.depth>=1)return!0}else e.nextCh===e.reverseSymb&&e.depth--;return!1}},section:{init:function(e){e.curMoveThrough=!0,e.symb=(e.forward?"]":"[")===e.symb?"{":"}"},isComplete:function(e){return 0===e.index&&e.nextCh===e.symb}},comment:{isComplete:function(e){var t="*"===e.lastCh&&"/"===e.nextCh;return e.lastCh=e.nextCh,t}},method:{init:function(e){e.symb="m"===e.symb?"{":"}",e.reverseSymb="{"===e.symb?"}":"{"},isComplete:function(e){return e.nextCh===e.symb}},preprocess:{init:function(e){e.index=0},isComplete:function(e){if("#"===e.nextCh){var t=e.lineText.match(/#(\w+)/)[1];if("endif"===t){if(e.forward&&0===e.depth)return!0;e.depth++}else if("if"===t){if(!e.forward&&0===e.depth)return!0;e.depth--}if("else"===t&&0===e.depth)return!0}return!1}}};function Ce(e,t,n,r,i){var o=t.line,a=t.ch,l=e.getLine(o),s=n?1:-1,c=r?p:h;if(i&&""==l){if(o+=s,l=e.getLine(o),!w(e,o))return null;a=n?0:l.length}for(;;){if(i&&""==l)return{from:0,to:0,line:o};for(var u=s>0?l.length:-1,f=u,d=u;a!=u;){for(var m=!1,g=0;g0?0:l.length}}function Se(e,t,n,i){for(var o,a=e.getCursor(),l=a.ch,s=0;s0;)d(u,i)&&n--,u+=i;return new r(u,0)}var h=e.state.vim;if(h.visualLine&&d(l,1,!0)){var p=h.sel.anchor;d(p.line,-1,!0)&&(o&&p.line==l||(l+=1))}var m=f(l);for(u=l;u<=c&&n;u++)d(u,1,!0)&&(o&&f(u)==m||n--);for(a=new r(u,0),u>c&&!m?m=!0:o=!1,u=l;u>s&&(o&&f(u)!=m&&u!=l||!d(u,-1,!0));u--);return{start:new r(u,0),end:a}}function Ae(){}function Oe(e){var t=e.state.vim;return t.searchState_||(t.searchState_=new Ae)}function Ee(e,t,n,r,i){e.openDialog?e.openDialog(t,r,{bottom:!0,value:i.value,onKeyDown:i.onKeyDown,onKeyUp:i.onKeyUp,selectValueOnOpen:!1}):r(prompt(n,""))}function Ne(e,t){var n=Pe(e,t)||[];if(!n.length)return[];var r=[];if(0===n[0]){for(var i=0;i'+t+"",{bottom:!0,duration:5e3}):alert(t)}var Fe="(Javascript regexp)";function ze(e,t){var n=(t.prefix||"")+" "+(t.desc||""),r=function(e,t){var n=''+(e||"")+'';return t&&(n+=' '+t+""),n}(t.prefix,t.desc);Ee(e,r,n,t.onClose,t)}function We(e,t,n,r){if(t){var i=Oe(e),o=Be(t,!!n,!!r);if(o)return _e(e,o),function(e,t){if(e instanceof RegExp&&t instanceof RegExp){for(var n=["global","multiline","ignoreCase","source"],r=0;r=t&&e<=n:e==t}function Ue(e){var t=e.getScrollInfo(),n=e.coordsChar({left:0,top:6+t.top},"local"),r=t.clientHeight-10+t.top,i=e.coordsChar({left:0,top:r},"local");return{top:n.line,bottom:i.line}}function Ve(e,t,n){if("'"==n){var r=e.doc.history.done,i=r[r.length-2];return i&&i.ranges&&i.ranges[0].head}if("."==n){if(0==e.doc.history.lastModTime)return;var o=e.doc.history.done.filter(function(e){if(void 0!==e.changes)return e});o.reverse();var a=o[0].changes[0].to;return a}var l=t.marks[n];return l&&l.find()}var qe=function(){this.buildCommandMap_()};qe.prototype={processCommand:function(e,t,n){var r=this;e.operation(function(){e.curOp.isVimOp=!0,r._processCommand(e,t,n)})},_processCommand:function(t,n,r){var i=t.state.vim,o=I.registerController.getRegister(":"),a=o.toString();i.visualMode&&ge(t);var l=new e.StringStream(n);o.setText(n);var s,c,u=r||{};u.input=n;try{this.parseInput_(t,l,u)}catch(e){throw De(t,e),e}if(u.commandName){if(s=this.matchCommand_(u.commandName)){if(c=s.name,s.excludeFromCommandHistory&&o.setText(a),this.parseCommandArgs_(l,u,s),"exToKey"==s.type){for(var f=0;f0;t--){var n=e.substring(0,t);if(this.commandMap_[n]){var r=this.commandMap_[n];if(0===r.name.indexOf(e))return r}}return null},buildCommandMap_:function(){this.commandMap_={};for(var e=0;e
";if(n){n=n.join("");for(var o=0;o"}}else for(var l in r){var s=r[l].toString();s.length&&(i+='"'+l+" "+s+"
")}De(e,i)},sort:function(t,n){var i,o,a,l,s,c=function(){if(n.argString){var t=new e.StringStream(n.argString);if(t.eat("!")&&(i=!0),t.eol())return;if(!t.eatSpace())return"Invalid arguments";var r=t.match(/([dinuox]+)?\s*(\/.+\/)?\s*/);if(!r&&!t.eol())return"Invalid arguments";if(r[1]){o=-1!=r[1].indexOf("i"),a=-1!=r[1].indexOf("u");var c=-1!=r[1].indexOf("d")||-1!=r[1].indexOf("n")&&1,u=-1!=r[1].indexOf("x")&&1,f=-1!=r[1].indexOf("o")&&1;if(c+u+f>1)return"Invalid arguments";l=(c?"decimal":u&&"hex")||f&&"octal"}r[2]&&(s=new RegExp(r[2].substr(1,r[2].length-2),o?"i":""))}}();if(c)De(t,c+": "+n.argString);else{var u=n.line||t.firstLine(),f=n.lineEnd||n.line||t.lastLine();if(u!=f){var d=r(u,0),h=r(f,se(t,f)),p=t.getRange(d,h).split("\n"),m=s||("decimal"==l?/(-?)([\d]+)/:"hex"==l?/(-?)(?:0x)?([0-9a-f]+)/i:"octal"==l?/([0-7]+)/:null),g="decimal"==l?10:"hex"==l?16:"octal"==l?8:null,v=[],y=[];if(l||s)for(var b=0;b")}if(r){var h=0,p=function(){if(h"+s+" (y/n/a/q/l)",onKeyDown:function(n,r,i){switch(e.e_stop(n),e.keyName(n)){case"Y":h(),p();break;case"N":p();break;case"A":var o=c;c=void 0,t.operation(d),c=o;break;case"L":h();case"Q":case"Esc":case"Ctrl-C":case"Ctrl-[":m(i)}return u&&m(i),!0}}):(d(),void(c&&c()));De(t,"No matches for "+l.source)}(t,f,d,m,g,y,p,u,n.callback)}else De(t,"No previous substitute regular expression")},redo:e.commands.redo,undo:e.commands.undo,write:function(t){e.commands.save?e.commands.save(t):t.save&&t.save()},nohlsearch:function(e){Ke(e)},yank:function(e){var t=ne(e.getCursor()),n=t.line,r=e.getLine(n);I.registerController.pushText("0","yank",r,!0,!0)},delmarks:function(t,n){if(n.argString&&ce(n.argString))for(var r=t.state.vim,i=new e.StringStream(ce(n.argString));!i.eol();){i.eatSpace();var o=i.pos;if(!i.match(/[a-zA-Z]/,!1))return void De(t,"Invalid argument: "+n.argString.substring(o));var a=i.next();if(i.match("-",!0)){if(!i.match(/[a-zA-Z]/,!1))return void De(t,"Invalid argument: "+n.argString.substring(o));var l=a,s=i.next();if(!(k(l)&&k(s)||L(l)&&L(s)))return void De(t,"Invalid argument: "+l+"-");var c=l.charCodeAt(0),u=s.charCodeAt(0);if(c>=u)return void De(t,"Invalid argument: "+n.argString.substring(o));for(var f=0;f<=u-c;f++){var d=String.fromCharCode(c+f);delete r.marks[d]}}else delete r.marks[a]}else De(t,"Argument required")}},Ge=new qe;function Xe(t){var n=t.state.vim,r=I.macroModeState,i=I.registerController.getRegister("."),o=r.isPlaying,a=r.lastInsertModeChanges,l=[];if(!o){for(var s=a.inVisualBlock&&n.lastSelection?n.lastSelection.visualBlock.height:1,c=a.changes,l=[],u=0;u1&&(rt(t,n,n.insertModeRepeat-1,!0),n.lastEditInputState.repeatOverride=n.insertModeRepeat),delete n.insertModeRepeat,n.insertMode=!1,t.setCursor(t.getCursor().line,t.getCursor().ch-1),t.setOption("keyMap","vim"),t.setOption("disableInput",!0),t.toggleOverwrite(!1),i.setText(a.changes.join("")),e.signal(t,"vim-mode-change",{mode:"normal"}),r.isRecording&&function(e){if(!e.isPlaying){var t=e.latestRegister,n=I.registerController.getRegister(t);n&&n.pushInsertModeChanges&&n.pushInsertModeChanges(e.lastInsertModeChanges)}}(r)}function Ye(e){t.unshift(e)}function Ze(t,n,r,i){var o=I.registerController.getRegister(i);if(":"==i)return o.keyBuffer[0]&&Ge.processCommand(t,o.keyBuffer[0]),void(r.isPlaying=!1);var a=o.keyBuffer,l=0;r.isPlaying=!0,r.replaySearchQueries=o.searchQueries.slice(0);for(var s=0;s|<\w+>|./.exec(f),u=c[0],f=f.substring(c.index+u.length),e.Vim.handleKey(t,u,"macro"),n.insertMode){var d=o.insertModeChanges[l++].changes;I.macroModeState.lastInsertModeChanges.changes=d,it(t,d,1),Xe(t)}r.isPlaying=!1}function Je(e,t){var n=I.macroModeState,r=n.lastInsertModeChanges;if(!n.isPlaying)for(;t;){if(r.expectCursorActivityForChange=!0,"+input"==t.origin||"paste"==t.origin||void 0===t.origin){var i=t.text.join("\n");r.maybeReset&&(r.changes=[],r.maybeReset=!1),e.state.overwrite&&!/\n/.test(i)?r.changes.push([i]):r.changes.push(i)}t=t.next}}function Qe(t){var n=t.state.vim;if(n.insertMode){var r=I.macroModeState;if(r.isPlaying)return;var i=r.lastInsertModeChanges;i.expectCursorActivityForChange?i.expectCursorActivityForChange=!1:i.maybeReset=!0}else t.curOp.isVimOp||function(t,n){var r=t.getCursor("anchor"),i=t.getCursor("head");if(n.visualMode&&!t.somethingSelected()?ge(t,!1):n.visualMode||n.insertMode||!t.somethingSelected()||(n.visualMode=!0,n.visualLine=!1,e.signal(t,"vim-mode-change",{mode:"visual"})),n.visualMode){var o=ie(i,r)?0:-1,a=ie(i,r)?-1:0;i=Q(i,0,o),r=Q(r,0,a),n.sel={anchor:r,head:i},Le(t,n,"<",oe(i,r)),Le(t,n,">",ae(i,r))}else n.insertMode||(n.lastHPos=t.getCursor().ch)}(t,n);n.visualMode&&et(t)}function et(e){var t=e.state.vim,n=Z(e,ne(t.sel.head)),r=Q(n,0,1);t.fakeCursor&&t.fakeCursor.clear(),t.fakeCursor=e.markText(n,r,{className:"cm-animate-fat-cursor"})}function tt(e){this.keyName=e}function nt(t){var n=I.macroModeState,r=n.lastInsertModeChanges,i=e.keyName(t);i&&(-1==i.indexOf("Delete")&&-1==i.indexOf("Backspace")||e.lookupKey(i,"vim-insert",function(){return r.maybeReset&&(r.changes=[],r.maybeReset=!1),r.changes.push(new tt(i)),!0}))}function rt(e,t,n,r){var i=I.macroModeState;i.isPlaying=!0;var o=!!t.lastEditActionCommand,a=t.inputState;function l(){o?q.processAction(e,t,t.lastEditActionCommand):q.evalInput(e,t)}function s(n){if(i.lastInsertModeChanges.changes.length>0){n=t.lastEditActionCommand?n:1;var r=i.lastInsertModeChanges;it(e,r.changes,n)}}if(t.inputState=t.lastEditInputState,o&&t.lastEditActionCommand.interlaceInsertRepeat)for(var c=0;c50&&r.shift()}function o(e){return r[r.length-(e?Math.min(e,1):1)]||""}var a=null;function l(e,t,o,l,s){null==s&&(s=e.getRange(t,o)),"grow"==l&&a&&a.cm==e&&n(t,a.pos)&&e.isClean(a.gen)?function(e){if(!r.length)return i(e);r[r.length-1]+=e}(s):!1!==l&&i(s),e.replaceRange("",t,o,"+delete"),a="grow"==l?{cm:e,pos:t,gen:e.changeGeneration()}:null}function s(e,t,n){return e.findPosH(t,n,"char",!0)}function c(e,t,n){return e.findPosH(t,n,"word",!0)}function u(e,t,n){return e.findPosV(t,n,"line",e.doc.sel.goalColumn)}function f(e,t,n){return e.findPosV(t,n,"page",e.doc.sel.goalColumn)}function d(e,n,r){for(var i=n.line,o=e.getLine(i),a=/\S/.test(r<0?o.slice(0,n.ch):o.slice(n.ch)),l=e.firstLine(),s=e.lastLine();;){if((i+=r)s)return e.clipPos(t(i-r,r<0?0:null));o=e.getLine(i);var c=/\S/.test(o);if(c)a=!0;else if(a)return t(i,0)}}function h(e,n,r){for(var i=n.line,o=n.ch,a=e.getLine(n.line),l=!1;;){var s=a.charAt(o+(r<0?-1:0));if(s){if(l&&/[!?.]/.test(s))return t(i,o+(r>0?1:0));l||(l=/\w/.test(s)),o+=r}else{if(i==(r<0?e.firstLine():e.lastLine()))return t(i,o);if(a=e.getLine(i+r),!/\S/.test(a))return t(i,o);i+=r,o=r<0?a.length:0}}}function p(e,r,i){var o;if(e.findMatchingBracket&&(o=e.findMatchingBracket(r,{strict:!0}))&&o.match&&(o.forward?1:-1)==i)return i>0?t(o.to.line,o.to.ch+1):o.to;for(var a=!0;;a=!1){var l=e.getTokenAt(r),s=t(r.line,i<0?l.start:l.end);if(!(a&&i>0&&l.end==r.ch)&&/\w/.test(l.string))return s;var c=e.findPosH(s,i,"char");if(n(s,c))return r;r=c}}function m(e,t){var n=e.state.emacsPrefix;return n?(S(e),"-"==n?-1:Number(n)):t?null:1}function g(e){var t="string"==typeof e?function(t){t.execCommand(e)}:e;return function(e){var n=m(e);t(e);for(var r=1;r1&&"+input"==t.origin){for(var r=t.text.join("\n"),i="",o=1;o1&&r.pop(),o()),"around","paste")},"Ctrl-Space":T,"Ctrl-Shift-2":T,"Ctrl-F":y(s,1),"Ctrl-B":y(s,-1),Right:y(s,1),Left:y(s,-1),"Ctrl-D":function(e){b(e,s,1,!1)},Delete:function(e){x(e,!1)||b(e,s,1,!1)},"Ctrl-H":function(e){b(e,s,-1,!1)},Backspace:function(e){x(e,!1)||b(e,s,-1,!1)},"Alt-F":y(c,1),"Alt-B":y(c,-1),"Alt-Right":y(c,1),"Alt-Left":y(c,-1),"Alt-D":function(e){b(e,c,1,"grow")},"Alt-Backspace":function(e){b(e,c,-1,"grow")},"Ctrl-N":y(u,1),"Ctrl-P":y(u,-1),Down:y(u,1),Up:y(u,-1),"Ctrl-A":"goLineStart","Ctrl-E":"goLineEnd",End:"goLineEnd",Home:"goLineStart","Alt-V":y(f,-1),"Ctrl-V":y(f,1),PageUp:y(f,-1),PageDown:y(f,1),"Ctrl-Up":y(d,-1),"Ctrl-Down":y(d,1),"Alt-A":y(h,-1),"Alt-E":y(h,1),"Alt-K":function(e){b(e,h,1,"grow")},"Ctrl-Alt-K":function(e){b(e,p,1,"grow")},"Ctrl-Alt-Backspace":function(e){b(e,p,-1,"grow")},"Ctrl-Alt-F":y(p,1),"Ctrl-Alt-B":y(p,-1),"Shift-Ctrl-Alt-2":function(e){var t=e.getCursor();e.setSelection(v(e,t,p,1),t)},"Ctrl-Alt-T":function(e){var t=p(e,e.getCursor(),-1),n=p(e,t,1),r=p(e,n,1),i=p(e,r,-1);e.replaceRange(e.getRange(i,r)+e.getRange(n,i)+e.getRange(t,n),t,r)},"Ctrl-Alt-U":g(function(e){for(var n=e.getCursor(),r=n.line,i=n.ch,o=[];r>=e.firstLine();){for(var a=e.getLine(r),l=null==i?a.length:i;l>0;){var i=a.charAt(--l);if(")"==i)o.push("(");else if("]"==i)o.push("[");else if("}"==i)o.push("{");else if(/[\(\{\[]/.test(i)&&(!o.length||o.pop()!=i))return e.extendSelection(t(r,l))}--r,i=null}}),"Alt-Space":function(e){for(var n=e.getCursor(),r=n.ch,i=n.ch,o=e.getLine(n.line);r&&/\s/.test(o.charAt(r-1));)--r;for(;i0)return e.setCursor(t-1);!function(e,t,n){e.openDialog?e.openDialog(t+': ',n,{bottom:!0}):n(prompt(t,""))}(e,"Goto line",function(t){var n;t&&!isNaN(n=Number(t))&&n==(0|n)&&n>0&&e.setCursor(n-1)})},"Ctrl-X Tab":function(e){e.indentSelection(m(e,!0)||e.getOption("indentUnit"))},"Ctrl-X Ctrl-X":function(e){e.setSelection(e.getCursor("head"),e.getCursor("anchor"))},"Ctrl-X Ctrl-S":"save","Ctrl-X Ctrl-W":"save","Ctrl-X S":"saveAll","Ctrl-X F":"open","Ctrl-X U":g("undo"),"Ctrl-X K":"close","Ctrl-X Delete":function(e){l(e,e.getCursor(),h(e,e.getCursor(),1),"grow")},"Ctrl-X H":"selectAll","Ctrl-Q Tab":g("insertTab"),"Ctrl-U":function(e){e.state.emacsPrefixMap=!0,e.addKeyMap(N),e.on("keyHandled",M),e.on("inputRead",M)}}),N={"Ctrl-G":S};function P(e){N[e]=function(t){w(t,e)},E["Ctrl-"+e]=function(t){w(t,e)},k["Ctrl-"+e]=!0}for(var I=0;I<10;++I)P(String(I));P("-")}(n(0))},function(e,t,n){!function(e){e.defineOption("showTrailingSpace",!1,function(t,n,r){r==e.Init&&(r=!1),r&&!n?t.removeOverlay("trailingspace"):!r&&n&&t.addOverlay({token:function(e){for(var t=e.string.length,n=t;n&&/\s/.test(e.string.charAt(n-1));--n);return n>e.pos?(e.pos=n,null):(e.pos=t,"trailingspace")},name:"trailingspace"})})}(n(0))},function(e,t,n){!function(e){"use strict";var t="CodeMirror-activeline",n="CodeMirror-activeline-background",r="CodeMirror-activeline-gutter";function i(e){for(var i=0;i>u",">>s",">=","<=","==","!=","=s",">=u",">s",">u","<",">","=","&","|","^","!"]);function l(e,t){var n;for(t.commentDepth=1;null!=(n=e.next());){if("*"===n&&e.eat("/")&&0==--t.commentDepth)return t.tokenize=null,"comment";"/"===n&&e.eat("*")&&t.commentDepth++}return"comment"}function s(e,t){for(var n,r=t.commentState;null!=(n=e.next());)if(0===r&&"t"===n)r=1;else if(1===r&&":"===n)return t.tokenize=null,t.commentState=0,r=2,"comment";return t.commentState=r,"comment"}return{startState:function(){return{tokenize:null,commentState:0,commentDepth:0}},token:function(n,c){if(n.eatSpace())return null;var u=(c.tokenize||function(n,c){var u=n.next();if("$"===u)return n.eatWhile(t),"variable";if("@"===u)return n.eatWhile(t),"meta";if('"'===u)return c.tokenize=function(e){return function(t,n){for(var r,i=!1;null!=(r=t.next());){if(r==e&&!i)return n.tokenize=null,"string";i=!i&&"\\"===r}return"string"}}(u),c.tokenize(n,c);if("/"==u){if(n.eat("*"))return c.tokenize=l,l(n,c);if(n.eat("/"))return n.skipToEnd(),"comment"}if(/\d/.test(u)||("-"===u||"+"===u)&&/\d/.test(n.peek()))return n.eatWhile(/[\w\._\-+]/),"number";if(/[\[\]\(\)\{\},:]/.test(u))return null;if(o.test(u))return"operator";n.eatWhile(t);var f=n.current();if(f in a)return"operator";if(f in e)return"keyword";if(f in i){if(!n.eat(":"))return"builtin";n.eatWhile(t),f=n.current()}return f in r?"builtin":"Temporary"===f?(c.tokenize=s,c.tokenize(n,c)):null})(n,c);return u}}}),e.registerHelper("wordChars","wasm",t),e.defineMIME("text/wasm","wasm")})?r.apply(t,i):r)||(e.exports=o)},function(e,t,n){!function(e){"use strict";function t(e,t,n,r,i,o){this.indented=e,this.column=t,this.type=n,this.info=r,this.align=i,this.prev=o}function n(e,n,r,i){var o=e.indented;return e.context&&"statement"==e.context.type&&"statement"!=r&&(o=e.context.indented),e.context=new t(o,n,r,i,null,e.context)}function r(e){var t=e.context.type;return")"!=t&&"]"!=t&&"}"!=t||(e.indented=e.context.indented),e.context=e.context.prev}function i(e,t,n){return"variable"==t.prevToken||"type"==t.prevToken||!!/\S(?:[^- ]>|[*\]])\s*$|\*$/.test(e.string.slice(0,n))||!(!t.typeAtEndOfLine||e.column()!=e.indentation())||void 0}function o(e){for(;;){if(!e||"top"==e.type)return!0;if("}"==e.type&&"namespace"!=e.prev.info)return!1;e=e.prev}}function a(e){for(var t={},n=e.split(" "),r=0;r!?|\/]/,O=s.isIdentifierChar||/[\w\$_\xa1-\uffff]/;function E(e,t){var n=e.next();if(x[n]){var r=x[n](e,t);if(!1!==r)return r}if('"'==n||"'"==n)return t.tokenize=function(e){return function(t,n){for(var r,i=!1,o=!1;null!=(r=t.next());){if(r==e&&!i){o=!0;break}i=!i&&"\\"==r}return(o||!i&&!w)&&(n.tokenize=null),"string"}}(n),t.tokenize(e,t);if(L.test(n))return c=n,null;if(M.test(n)){if(e.backUp(1),e.match(T))return"number";e.next()}if("/"==n){if(e.eat("*"))return t.tokenize=N,N(e,t);if(e.eat("/"))return e.skipToEnd(),"comment"}if(A.test(n)){for(;!e.match(/^\/[\/*]/,!1)&&e.eat(A););return"operator"}if(e.eatWhile(O),S)for(;e.match(S);)e.eatWhile(O);var i=e.current();return l(p,i)?(l(v,i)&&(c="newstatement"),l(y,i)&&(u=!0),"keyword"):l(m,i)?"type":l(g,i)?(l(v,i)&&(c="newstatement"),"builtin"):l(b,i)?"atom":"variable"}function N(e,t){for(var n,r=!1;n=e.next();){if("/"==n&&r){t.tokenize=null;break}r="*"==n}return"comment"}function P(e,t){s.typeFirstDefinitions&&e.eol()&&o(t.context)&&(t.typeAtEndOfLine=i(e,t,e.pos))}return{startState:function(e){return{tokenize:null,context:new t((e||0)-f,0,"top",null,!1),indented:0,startOfLine:!0,prevToken:null}},token:function(e,t){var a=t.context;if(e.sol()&&(null==a.align&&(a.align=!1),t.indented=e.indentation(),t.startOfLine=!0),e.eatSpace())return P(e,t),null;c=u=null;var l=(t.tokenize||E)(e,t);if("comment"==l||"meta"==l)return l;if(null==a.align&&(a.align=!0),";"==c||":"==c||","==c&&e.match(/^\s*(?:\/\/.*)?$/,!1))for(;"statement"==t.context.type;)r(t);else if("{"==c)n(t,e.column(),"}");else if("["==c)n(t,e.column(),"]");else if("("==c)n(t,e.column(),")");else if("}"==c){for(;"statement"==a.type;)a=r(t);for("}"==a.type&&(a=r(t));"statement"==a.type;)a=r(t)}else c==a.type?r(t):k&&(("}"==a.type||"top"==a.type)&&";"!=c||"statement"==a.type&&"newstatement"==c)&&n(t,e.column(),"statement",e.current());if("variable"==l&&("def"==t.prevToken||s.typeFirstDefinitions&&i(e,t,e.start)&&o(t.context)&&e.match(/^\s*\(/,!1))&&(l="def"),x.token){var f=x.token(e,t,l);void 0!==f&&(l=f)}return"def"==l&&!1===s.styleDefs&&(l="variable"),t.startOfLine=!1,t.prevToken=u?"def":l||c,P(e,t),l},indent:function(t,n){if(t.tokenize!=E&&null!=t.tokenize||t.typeAtEndOfLine)return e.Pass;var r=t.context,i=n&&n.charAt(0);if("statement"==r.type&&"}"==i&&(r=r.prev),s.dontIndentStatements)for(;"statement"==r.type&&s.dontIndentStatements.test(r.info);)r=r.prev;if(x.indent){var o=x.indent(t,r,n);if("number"==typeof o)return o}var a=i==r.type,l=r.prev&&"switch"==r.prev.info;if(s.allmanIndentation&&/[{(]/.test(i)){for(;"top"!=r.type&&"}"!=r.type;)r=r.prev;return r.indented}return"statement"==r.type?r.indented+("{"==i?0:d):!r.align||h&&")"==r.type?")"!=r.type||a?r.indented+(a?0:f)+(a||!l||/^(?:case|default)\b/.test(n)?0:f):r.indented+d:r.column+(a?0:1)},electricInput:C?/^\s*(?:case .*?:|default:|\{\}?|\})$/:/^\s*[{}]$/,blockCommentStart:"/*",blockCommentEnd:"*/",blockCommentContinue:" * ",lineComment:"//",fold:"brace"}});var s="auto if break case register continue return default do sizeof static else struct switch extern typedef union for goto while enum const volatile",c="int long char short double float unsigned signed void size_t ptrdiff_t";function u(e,t){if(!t.startOfLine)return!1;for(var n,r=null;n=e.peek();){if("\\"==n&&e.match(/^.$/)){r=u;break}if("/"==n&&e.match(/^\/[\/\*]/,!1))break;e.next()}return t.tokenize=r,"meta"}function f(e,t){return"type"==t.prevToken&&"type"}function d(e){return e.eatWhile(/[\w\.']/),"number"}function h(e,t){if(e.backUp(1),e.match(/(R|u8R|uR|UR|LR)/)){var n=e.match(/"([^\s\\()]{0,16})\(/);return!!n&&(t.cpp11RawStringDelim=n[1],t.tokenize=m,m(e,t))}return e.match(/(u8|u|U|L)/)?!!e.match(/["']/,!1)&&"string":(e.next(),!1)}function p(e,t){for(var n;null!=(n=e.next());)if('"'==n&&!e.eat('"')){t.tokenize=null;break}return"string"}function m(e,t){var n=t.cpp11RawStringDelim.replace(/[^\w\s]/g,"\\$&"),r=e.match(new RegExp(".*?\\)"+n+'"'));return r?t.tokenize=null:e.skipToEnd(),"string"}function g(t,n){"string"==typeof t&&(t=[t]);var r=[];function i(e){if(e)for(var t in e)e.hasOwnProperty(t)&&r.push(t)}i(n.keywords),i(n.types),i(n.builtin),i(n.atoms),r.length&&(n.helperType=t[0],e.registerHelper("hintWords",t[0],r));for(var o=0;o!?|\/#:@]/,hooks:{"@":function(e){return e.eatWhile(/[\w\$_]/),"meta"},'"':function(e,t){return!!e.match('""')&&(t.tokenize=v,t.tokenize(e,t))},"'":function(e){return e.eatWhile(/[\w\$_\xa1-\uffff]/),"atom"},"=":function(e,n){var r=n.context;return!("}"!=r.type||!r.align||!e.eat(">"))&&(n.context=new t(r.indented,r.column,r.type,r.info,null,r.prev),"operator")},"/":function(e,t){return!!e.eat("*")&&(t.tokenize=function e(t){return function(n,r){for(var i;i=n.next();){if("*"==i&&n.eat("/")){if(1==t){r.tokenize=null;break}return r.tokenize=e(t-1),r.tokenize(n,r)}if("/"==i&&n.eat("*"))return r.tokenize=e(t+1),r.tokenize(n,r)}return"comment"}}(1),t.tokenize(e,t))}},modeProps:{closeBrackets:{triples:'"'}}}),g("text/x-kotlin",{name:"clike",keywords:a("package as typealias class interface this super val operator var fun for is in This throw return annotation break continue object if else while do try when !in !is as? file import where by get set abstract enum open inner override private public internal protected catch finally out final vararg reified dynamic companion constructor init sealed field property receiver param sparam lateinit data inline noinline tailrec external annotation crossinline const operator infix suspend actual expect setparam"),types:a("Boolean Byte Character CharSequence Class ClassLoader Cloneable Comparable Compiler Double Exception Float Integer Long Math Number Object Package Pair Process Runtime Runnable SecurityManager Short StackTraceElement StrictMath String StringBuffer System Thread ThreadGroup ThreadLocal Throwable Triple Void Annotation Any BooleanArray ByteArray Char CharArray DeprecationLevel DoubleArray Enum FloatArray Function Int IntArray Lazy LazyThreadSafetyMode LongArray Nothing ShortArray Unit"),intendSwitch:!1,indentStatements:!1,multiLineStrings:!0,number:/^(?:0x[a-f\d_]+|0b[01_]+|(?:[\d_]+(\.\d+)?|\.\d+)(?:e[-+]?[\d_]+)?)(u|ll?|l|f)?/i,blockKeywords:a("catch class do else finally for if where try while enum"),defKeywords:a("class val var object interface fun"),atoms:a("true false null this"),hooks:{"@":function(e){return e.eatWhile(/[\w\$_]/),"meta"},'"':function(e,t){return t.tokenize=function(e){return function(t,n){for(var r,i=!1,o=!1;!t.eol();){if(!e&&!i&&t.match('"')){o=!0;break}if(e&&t.match('"""')){o=!0;break}r=t.next(),!i&&"$"==r&&t.match("{")&&t.skipTo("}"),i=!i&&"\\"==r&&!e}return!o&&e||(n.tokenize=null),"string"}}(e.match('""')),t.tokenize(e,t)}},modeProps:{closeBrackets:{triples:'"'}}}),g(["x-shader/x-vertex","x-shader/x-fragment"],{name:"clike",keywords:a("sampler1D sampler2D sampler3D samplerCube sampler1DShadow sampler2DShadow const attribute uniform varying break continue discard return for while do if else struct in out inout"),types:a("float int bool void vec2 vec3 vec4 ivec2 ivec3 ivec4 bvec2 bvec3 bvec4 mat2 mat3 mat4"),blockKeywords:a("for while do if else struct"),builtin:a("radians degrees sin cos tan asin acos atan pow exp log exp2 sqrt inversesqrt abs sign floor ceil fract mod min max clamp mix step smoothstep length distance dot cross normalize ftransform faceforward reflect refract matrixCompMult lessThan lessThanEqual greaterThan greaterThanEqual equal notEqual any all not texture1D texture1DProj texture1DLod texture1DProjLod texture2D texture2DProj texture2DLod texture2DProjLod texture3D texture3DProj texture3DLod texture3DProjLod textureCube textureCubeLod shadow1D shadow2D shadow1DProj shadow2DProj shadow1DLod shadow2DLod shadow1DProjLod shadow2DProjLod dFdx dFdy fwidth noise1 noise2 noise3 noise4"),atoms:a("true false gl_FragColor gl_SecondaryColor gl_Normal gl_Vertex gl_MultiTexCoord0 gl_MultiTexCoord1 gl_MultiTexCoord2 gl_MultiTexCoord3 gl_MultiTexCoord4 gl_MultiTexCoord5 gl_MultiTexCoord6 gl_MultiTexCoord7 gl_FogCoord gl_PointCoord gl_Position gl_PointSize gl_ClipVertex gl_FrontColor gl_BackColor gl_FrontSecondaryColor gl_BackSecondaryColor gl_TexCoord gl_FogFragCoord gl_FragCoord gl_FrontFacing gl_FragData gl_FragDepth gl_ModelViewMatrix gl_ProjectionMatrix gl_ModelViewProjectionMatrix gl_TextureMatrix gl_NormalMatrix gl_ModelViewMatrixInverse gl_ProjectionMatrixInverse gl_ModelViewProjectionMatrixInverse gl_TexureMatrixTranspose gl_ModelViewMatrixInverseTranspose gl_ProjectionMatrixInverseTranspose gl_ModelViewProjectionMatrixInverseTranspose gl_TextureMatrixInverseTranspose gl_NormalScale gl_DepthRange gl_ClipPlane gl_Point gl_FrontMaterial gl_BackMaterial gl_LightSource gl_LightModel gl_FrontLightModelProduct gl_BackLightModelProduct gl_TextureColor gl_EyePlaneS gl_EyePlaneT gl_EyePlaneR gl_EyePlaneQ gl_FogParameters gl_MaxLights gl_MaxClipPlanes gl_MaxTextureUnits gl_MaxTextureCoords gl_MaxVertexAttribs gl_MaxVertexUniformComponents gl_MaxVaryingFloats gl_MaxVertexTextureImageUnits gl_MaxTextureImageUnits gl_MaxFragmentUniformComponents gl_MaxCombineTextureImageUnits gl_MaxDrawBuffers"),indentSwitch:!1,hooks:{"#":u},modeProps:{fold:["brace","include"]}}),g("text/x-nesc",{name:"clike",keywords:a(s+"as atomic async call command component components configuration event generic implementation includes interface module new norace nx_struct nx_union post provides signal task uses abstract extends"),types:a(c),blockKeywords:a("case do else for if switch while struct"),atoms:a("null true false"),hooks:{"#":u},modeProps:{fold:["brace","include"]}}),g("text/x-objectivec",{name:"clike",keywords:a(s+"inline restrict _Bool _Complex _Imaginary BOOL Class bycopy byref id IMP in inout nil oneway out Protocol SEL self super atomic nonatomic retain copy readwrite readonly"),types:a(c),atoms:a("YES NO NULL NILL ON OFF true false"),hooks:{"@":function(e){return e.eatWhile(/[\w\$]/),"keyword"},"#":u,indent:function(e,t,n){if("statement"==t.type&&/^@\w/.test(n))return t.indented}},modeProps:{fold:"brace"}}),g("text/x-squirrel",{name:"clike",keywords:a("base break clone continue const default delete enum extends function in class foreach local resume return this throw typeof yield constructor instanceof static"),types:a(c),blockKeywords:a("case catch class else for foreach if switch try while"),defKeywords:a("function local class"),typeFirstDefinitions:!0,atoms:a("true false null"),hooks:{"#":u},modeProps:{fold:["brace","include"]}});var y=null;g("text/x-ceylon",{name:"clike",keywords:a("abstracts alias assembly assert assign break case catch class continue dynamic else exists extends finally for function given if import in interface is let module new nonempty object of out outer package return satisfies super switch then this throw try value void while"),types:function(e){var t=e.charAt(0);return t===t.toUpperCase()&&t!==t.toLowerCase()},blockKeywords:a("case catch class dynamic else finally for function if interface module new object switch try while"),defKeywords:a("class dynamic function interface module object package value"),builtin:a("abstract actual aliased annotation by default deprecated doc final formal late license native optional sealed see serializable shared suppressWarnings tagged throws variable"),isPunctuationChar:/[\[\]{}\(\),;\:\.`]/,isOperatorChar:/[+\-*&%=<>!?|^~:\/]/,numberStart:/[\d#$]/,number:/^(?:#[\da-fA-F_]+|\$[01_]+|[\d_]+[kMGTPmunpf]?|[\d_]+\.[\d_]+(?:[eE][-+]?\d+|[kMGTPmunpf]|)|)/i,multiLineStrings:!0,typeFirstDefinitions:!0,atoms:a("true false null larger smaller equal empty finished"),indentSwitch:!1,styleDefs:!1,hooks:{"@":function(e){return e.eatWhile(/[\w\$_]/),"meta"},'"':function(e,t){return t.tokenize=function e(t){return function(n,r){for(var i,o=!1,a=!1;!n.eol();){if(!o&&n.match('"')&&("single"==t||n.match('""'))){a=!0;break}if(!o&&n.match("``")){y=e(t),a=!0;break}i=n.next(),o="single"==t&&!o&&"\\"==i}return a&&(r.tokenize=null),"string"}}(e.match('""')?"triple":"single"),t.tokenize(e,t)},"`":function(e,t){return!(!y||!e.match("`"))&&(t.tokenize=y,y=null,t.tokenize(e,t))},"'":function(e){return e.eatWhile(/[\w\$_\xa1-\uffff]/),"atom"},token:function(e,t,n){if(("variable"==n||"type"==n)&&"."==t.prevToken)return"variable-2"}},modeProps:{fold:["brace","import"],closeBrackets:{triples:'"'}}})}(n(0))},function(e,t,n){!function(e){"use strict";e.defineMode("elm",function(){function e(e,t,n){return t(n),n(e,t)}var t=/[a-z_]/,n=/[A-Z]/,r=/[0-9]/,i=/[0-9A-Fa-f]/,o=/[0-7]/,a=/[a-z_A-Z0-9\']/,l=/[-!#$%&*+.\/<=>?@\\^|~:\u03BB\u2192]/,s=/[(),;[\]`{}]/,c=/[ \t\v\f]/;function u(){return function(d,h){if(d.eatWhile(c))return null;var p=d.next();if(s.test(p)){if("{"==p&&d.eat("-")){var m="comment";return d.eat("#")&&(m="meta"),e(d,h,function e(t,n){return 0==n?u():function(r,i){for(var o=n;!r.eol();){var a=r.next();if("{"==a&&r.eat("-"))++o;else if("-"==a&&r.eat("}")&&0==--o)return i(u()),t}return i(e(t,o)),t}}(m,1))}return null}if("'"==p)return d.eat("\\"),d.next(),d.eat("'")?"string":"error";if('"'==p)return e(d,h,f);if(n.test(p))return d.eatWhile(a),d.eat(".")?"qualifier":"variable-2";if(t.test(p)){var g=1===d.pos;return d.eatWhile(a),g?"type":"variable"}if(r.test(p)){if("0"==p){if(d.eat(/[xX]/))return d.eatWhile(i),"integer";if(d.eat(/[oO]/))return d.eatWhile(o),"number"}d.eatWhile(r);var m="number";return d.eat(".")&&(m="number",d.eatWhile(r)),d.eat(/[eE]/)&&(m="number",d.eat(/[-+]/),d.eatWhile(r)),m}return l.test(p)?"-"==p&&d.eat(/-/)&&(d.eatWhile(/-/),!d.eat(l))?(d.skipToEnd(),"comment"):(d.eatWhile(l),"builtin"):"error"}}function f(e,t){for(;!e.eol();){var n=e.next();if('"'==n)return t(u()),"string";if("\\"==n){if(e.eol()||e.eat(c))return t(d),"string";e.eat("&")||e.next()}}return t(u()),"error"}function d(t,n){return t.eat("\\")?e(t,n,f):(t.next(),n(u()),"error")}var h=function(){for(var e={},t=["case","of","as","if","then","else","let","in","infix","infixl","infixr","type","alias","input","output","foreign","loopback","module","where","import","exposing","_","..","|",":","=","\\",'"',"->","<-"],n=t.length;n--;)e[t[n]]="keyword";return e}();return{startState:function(){return{f:u()}},copyState:function(e){return{f:e.f}},token:function(e,t){var n=t.f(e,function(e){t.f=e}),r=e.current();return h.hasOwnProperty(r)?h[r]:n}}}),e.defineMIME("text/x-elm","elm")}(n(0))},function(e,t,n){!function(e){"use strict";e.defineMode("coffeescript",function(e,t){var n="error";function r(e){return new RegExp("^(("+e.join(")|(")+"))\\b")}var i=/^(?:->|=>|\+[+=]?|-[\-=]?|\*[\*=]?|\/[\/=]?|[=!]=|<[><]?=?|>>?=?|%=?|&=?|\|=?|\^=?|\~|!|\?|(or|and|\|\||&&|\?)=)/,o=/^(?:[()\[\]{},:`=;]|\.\.?\.?)/,a=/^[_A-Za-z$][_A-Za-z$0-9]*/,l=/^@[_A-Za-z$][_A-Za-z$0-9]*/,s=r(["and","or","not","is","isnt","in","instanceof","typeof"]),c=["for","while","loop","if","unless","else","switch","try","catch","finally","class"],u=r(c.concat(["break","by","continue","debugger","delete","do","in","of","new","return","then","this","@","throw","when","until","extends"]));c=r(c);var f=/^('{3}|\"{3}|['\"])/,d=/^(\/{3}|\/)/,h=r(["Infinity","NaN","undefined","null","true","false","on","off","yes","no"]);function p(e,t){if(e.sol()){null===t.scope.align&&(t.scope.align=!1);var r=t.scope.offset;if(e.eatSpace()){var c=e.indentation();return c>r&&"coffee"==t.scope.type?"indent":c0&&y(e,t)}if(e.eatSpace())return null;var p=e.peek();if(e.match("####"))return e.skipToEnd(),"comment";if(e.match("###"))return t.tokenize=g,t.tokenize(e,t);if("#"===p)return e.skipToEnd(),"comment";if(e.match(/^-?[0-9\.]/,!1)){var v=!1;if(e.match(/^-?\d*\.\d+(e[\+\-]?\d+)?/i)&&(v=!0),e.match(/^-?\d+\.\d*/)&&(v=!0),e.match(/^-?\.\d+/)&&(v=!0),v)return"."==e.peek()&&e.backUp(1),"number";var b=!1;if(e.match(/^-?0x[0-9a-f]+/i)&&(b=!0),e.match(/^-?[1-9]\d*(e[\+\-]?\d+)?/)&&(b=!0),e.match(/^-?0(?![\dx])/i)&&(b=!0),b)return"number"}if(e.match(f))return t.tokenize=m(e.current(),!1,"string"),t.tokenize(e,t);if(e.match(d)){if("/"!=e.current()||e.match(/^.*\//,!1))return t.tokenize=m(e.current(),!0,"string-2"),t.tokenize(e,t);e.backUp(1)}return e.match(i)||e.match(s)?"operator":e.match(o)?"punctuation":e.match(h)?"atom":e.match(l)||t.prop&&e.match(a)?"property":e.match(u)?"keyword":e.match(a)?"variable":(e.next(),n)}function m(e,r,i){return function(o,a){for(;!o.eol();)if(o.eatWhile(/[^'"\/\\]/),o.eat("\\")){if(o.next(),r&&o.eol())return i}else{if(o.match(e))return a.tokenize=p,i;o.eat(/['"\/]/)}return r&&(t.singleLineStringErrors?i=n:a.tokenize=p),i}}function g(e,t){for(;!e.eol();){if(e.eatWhile(/[^#]/),e.match("###")){t.tokenize=p;break}e.eatWhile("#")}return"comment"}function v(t,n,r){r=r||"coffee";for(var i=0,o=!1,a=null,l=n.scope;l;l=l.prev)if("coffee"===l.type||"}"==l.type){i=l.offset+e.indentUnit;break}"coffee"!==r?(o=null,a=t.column()+t.current().length):n.scope.align&&(n.scope.align=!1),n.scope={offset:i,type:r,prev:n.scope,align:o,alignOffset:a}}function y(e,t){if(t.scope.prev){if("coffee"===t.scope.type){for(var n=e.indentation(),r=!1,i=t.scope;i;i=i.prev)if(n===i.offset){r=!0;break}if(!r)return!0;for(;t.scope.prev&&t.scope.offset!==n;)t.scope=t.scope.prev;return!1}return t.scope=t.scope.prev,!1}}var b={startState:function(e){return{tokenize:p,scope:{offset:e||0,type:"coffee",prev:null,align:!1},prop:!1,dedent:0}},token:function(e,t){var r=null===t.scope.align&&t.scope;r&&e.sol()&&(r.align=!1);var i=function(e,t){var r=t.tokenize(e,t),i=e.current();"return"===i&&(t.dedent=!0),(("->"===i||"=>"===i)&&e.eol()||"indent"===r)&&v(e,t);var o="[({".indexOf(i);if(-1!==o&&v(e,t,"])}".slice(o,o+1)),c.exec(i)&&v(e,t),"then"==i&&y(e,t),"dedent"===r&&y(e,t))return n;if(-1!==(o="])}".indexOf(i))){for(;"coffee"==t.scope.type&&t.scope.prev;)t.scope=t.scope.prev;t.scope.type==i&&(t.scope=t.scope.prev)}return t.dedent&&e.eol()&&("coffee"==t.scope.type&&t.scope.prev&&(t.scope=t.scope.prev),t.dedent=!1),r}(e,t);return i&&"comment"!=i&&(r&&(r.align=!0),t.prop="punctuation"==i&&"."==e.current()),i},indent:function(e,t){if(e.tokenize!=p)return 0;var n=e.scope,r=t&&"])}".indexOf(t.charAt(0))>-1;if(r)for(;"coffee"==n.type&&n.prev;)n=n.prev;var i=r&&n.type===t.charAt(0);return n.align?n.alignOffset-(i?1:0):(i?n.prev:n).offset},lineComment:"#",fold:"indent"};return b}),e.defineMIME("application/vnd.coffeescript","coffeescript"),e.defineMIME("text/x-coffeescript","coffeescript"),e.defineMIME("text/coffeescript","coffeescript")}(n(0))},function(e,t,n){!function(e){"use strict";function t(e,t,n,r){this.state=e,this.mode=t,this.depth=n,this.prev=r}e.defineMode("jsx",function(n,r){var i=e.getMode(n,{name:"xml",allowMissing:!0,multilineTagIndentPastTag:!1,allowMissingTagName:!0}),o=e.getMode(n,r&&r.base||"javascript");function a(e){var t=e.tagName;e.tagName=null;var n=i.indent(e,"");return e.tagName=t,n}function l(r,s){return s.context.mode==i?function(r,s,c){if(2==c.depth)return r.match(/^.*?\*\//)?c.depth=1:r.skipToEnd(),"comment";if("{"==r.peek()){i.skipAttribute(c.state);var u=a(c.state),f=c.state.context;if(f&&r.match(/^[^>]*>\s*$/,!1)){for(;f.prev&&!f.startOfLine;)f=f.prev;f.startOfLine?u-=n.indentUnit:c.prev.state.lexical&&(u=c.prev.state.lexical.indented)}else 1==c.depth&&(u+=n.indentUnit);return s.context=new t(e.startState(o,u),o,0,s.context),null}if(1==c.depth){if("<"==r.peek())return i.skipAttribute(c.state),s.context=new t(e.startState(i,a(c.state)),i,0,s.context),null;if(r.match("//"))return r.skipToEnd(),"comment";if(r.match("/*"))return c.depth=2,l(r,s)}var d,h=i.token(r,c.state),p=r.current();return/\btag\b/.test(h)?/>$/.test(p)?c.state.context?c.depth=0:s.context=s.context.prev:/^-1&&r.backUp(p.length-d),h}(r,s,s.context):function(n,r,a){if("<"==n.peek()&&o.expressionAllowed(n,a.state))return o.skipExpression(a.state),r.context=new t(e.startState(i,o.indent(a.state,"")),i,0,r.context),null;var l=o.token(n,a.state);if(!l&&null!=a.depth){var s=n.current();"{"==s?a.depth++:"}"==s&&0==--a.depth&&(r.context=r.context.prev)}return l}(r,s,s.context)}return{startState:function(){return{context:new t(e.startState(o),o)}},copyState:function(n){return{context:function n(r){return new t(e.copyState(r.mode,r.state),r.mode,r.depth,r.prev&&n(r.prev))}(n.context)}},token:l,indent:function(e,t,n){return e.context.mode.indent(e.context.state,t,n)},innerMode:function(e){return e.context}}},"xml","javascript"),e.defineMIME("text/jsx","jsx"),e.defineMIME("text/typescript-jsx",{name:"jsx",base:{name:"javascript",typescript:!0}})}(n(0),n(2),n(3))},function(e,t,n){!function(e){"use strict";var t={script:[["lang",/(javascript|babel)/i,"javascript"],["type",/^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^module$|^$/i,"javascript"],["type",/./,"text/plain"],[null,null,"javascript"]],style:[["lang",/^css$/i,"css"],["type",/^(text\/)?(x-)?(stylesheet|css)$/i,"css"],["type",/./,"text/plain"],[null,null,"css"]]},n={};function r(e,t){var r=e.match(function(e){var t=n[e];return t||(n[e]=new RegExp("\\s+"+e+"\\s*=\\s*('|\")?([^'\"]+)('|\")?\\s*"))}(t));return r?/^\s*(.*?)\s*$/.exec(r[2])[1]:""}function i(e,t){return new RegExp((t?"^":"")+"","i")}function o(e,t){for(var n in e)for(var r=t[n]||(t[n]=[]),i=e[n],o=i.length-1;o>=0;o--)r.unshift(i[o])}e.defineMode("htmlmixed",function(n,a){var l=e.getMode(n,{name:"xml",htmlMode:!0,multilineTagIndentFactor:a.multilineTagIndentFactor,multilineTagIndentPastTag:a.multilineTagIndentPastTag}),s={},c=a&&a.tags,u=a&&a.scriptTypes;if(o(t,s),c&&o(c,s),u)for(var f=u.length-1;f>=0;f--)s.script.unshift(["type",u[f].matches,u[f].mode]);function d(t,o){var a,c=l.token(t,o.htmlState),u=/\btag\b/.test(c);if(u&&!/[<>\s\/]/.test(t.current())&&(a=o.htmlState.tagName&&o.htmlState.tagName.toLowerCase())&&s.hasOwnProperty(a))o.inTag=a+" ";else if(o.inTag&&u&&/>$/.test(t.current())){var f=/^([\S]+) (.*)/.exec(o.inTag);o.inTag=null;var h=">"==t.current()&&function(e,t){for(var n=0;n-1?e.backUp(r.length-i):r.match(/<\/?$/)&&(e.backUp(r.length),e.match(t,!1)||e.match(r)),n}(e,g,t.localMode.token(e,t.localState))},o.localMode=p,o.localState=e.startState(p,l.indent(o.htmlState,""))}else o.inTag&&(o.inTag+=t.current(),t.eol()&&(o.inTag+=" "));return c}return{startState:function(){var t=e.startState(l);return{token:d,inTag:null,localMode:null,localState:null,htmlState:t}},copyState:function(t){var n;return t.localState&&(n=e.copyState(t.localMode,t.localState)),{token:t.token,inTag:t.inTag,localMode:t.localMode,localState:n,htmlState:e.copyState(l,t.htmlState)}},token:function(e,t){return t.token(e,t)},indent:function(t,n,r){return!t.localMode||/^\s*<\//.test(n)?l.indent(t.htmlState,n):t.localMode.indent?t.localMode.indent(t.localState,n,r):e.Pass},innerMode:function(e){return{state:e.localState||e.htmlState,mode:e.localMode||l}}}},"xml","javascript","css"),e.defineMIME("text/html","htmlmixed")}(n(0),n(2),n(3),n(7))},function(e,t,n){!function(e){"use strict";e.defineMode("haxe",function(e,t){var n=e.indentUnit;function r(e){return{type:e,style:"keyword"}}var i,o=r("keyword a"),a=r("keyword b"),l=r("keyword c"),s=r("operator"),c={type:"atom",style:"atom"},u={type:"attribute",style:"attribute"},f=r("typedef"),d={if:o,while:o,else:a,do:a,try:a,return:l,break:l,continue:l,new:l,throw:l,var:r("var"),inline:u,static:u,using:r("import"),public:u,private:u,cast:r("cast"),import:r("import"),macro:r("macro"),function:r("function"),catch:r("catch"),untyped:r("untyped"),callback:r("cb"),for:r("for"),switch:r("switch"),case:r("case"),default:r("default"),in:s,never:r("property_access"),trace:r("trace"),class:f,abstract:f,enum:f,interface:f,typedef:f,extends:f,implements:f,dynamic:f,true:c,false:c,null:c},h=/[+\-*&%=<>!?|]/;function p(e,t,n){return t.tokenize=n,n(e,t)}function m(e,t){for(var n,r=!1;null!=(n=e.next());){if(n==t&&!r)return!0;r=!r&&"\\"==n}}function g(e,t,n){return f=e,i=n,t}function v(e,t){var n=e.next();if('"'==n||"'"==n)return p(e,t,function(e){return function(t,n){return m(t,e)&&(n.tokenize=v),g("string","string")}}(n));if(/[\[\]{}\(\),;\:\.]/.test(n))return g(n);if("0"==n&&e.eat(/x/i))return e.eatWhile(/[\da-f]/i),g("number","number");if(/\d/.test(n)||"-"==n&&e.eat(/\d/))return e.match(/^\d*(?:\.\d*(?!\.))?(?:[eE][+\-]?\d+)?/),g("number","number");if(t.reAllowed&&"~"==n&&e.eat(/\//))return m(e,"/"),e.eatWhile(/[gimsu]/),g("regexp","string-2");if("/"==n)return e.eat("*")?p(e,t,y):e.eat("/")?(e.skipToEnd(),g("comment","comment")):(e.eatWhile(h),g("operator",null,e.current()));if("#"==n)return e.skipToEnd(),g("conditional","meta");if("@"==n)return e.eat(/:/),e.eatWhile(/[\w_]/),g("metadata","meta");if(h.test(n))return e.eatWhile(h),g("operator",null,e.current());if(/[A-Z]/.test(n))return e.eatWhile(/[\w_<>]/),g("type","variable-3",r=e.current());e.eatWhile(/[\w_]/);var r=e.current(),i=d.propertyIsEnumerable(r)&&d[r];return i&&t.kwAllowed?g(i.type,i.style,r):g("variable","variable",r)}function y(e,t){for(var n,r=!1;n=e.next();){if("/"==n&&r){t.tokenize=v;break}r="*"==n}return g("comment","comment")}var b={atom:!0,number:!0,variable:!0,string:!0,regexp:!0};function x(e,t,n,r,i,o){this.indented=e,this.column=t,this.type=n,this.prev=i,this.info=o,null!=r&&(this.align=r)}function w(e,t){for(var n=e.localVars;n;n=n.next)if(n.name==t)return!0}function k(e,t){if(/[a-z]/.test(t.charAt(0)))return!1;for(var n=e.importedtypes.length,r=0;r=0;e--)S.cc.push(arguments[e])}function M(){return L.apply(null,arguments),!0}function T(e,t){for(var n=t;n;n=n.next)if(n.name==e)return!0;return!1}function A(e){var t=S.state;if(t.context){if(S.marked="def",T(e,t.localVars))return;t.localVars={name:e,next:t.localVars}}else if(t.globalVars){if(T(e,t.globalVars))return;t.globalVars={name:e,next:t.globalVars}}}var O={name:"this",next:null};function E(){S.state.context||(S.state.localVars=O),S.state.context={prev:S.state.context,vars:S.state.localVars}}function N(){S.state.localVars=S.state.context.vars,S.state.context=S.state.context.prev}function P(e,t){var n=function(){var n=S.state;n.lexical=new x(n.indented,S.stream.column(),e,null,n.lexical,t)};return n.lex=!0,n}function I(){var e=S.state;e.lexical.prev&&(")"==e.lexical.type&&(e.indented=e.lexical.indented),e.lexical=e.lexical.prev)}function R(e){return function t(n){return n==e?M():";"==e?L():M(t)}}function B(e){return"@"==e?M(_):"var"==e?M(P("vardef"),X,R(";"),I):"keyword a"==e?M(P("form"),D,B,I):"keyword b"==e?M(P("form"),B,I):"{"==e?M(P("}"),E,G,I,N):";"==e?M():"attribute"==e?M(W):"function"==e?M(Q):"for"==e?M(P("form"),R("("),P(")"),Z,R(")"),I,B,I):"variable"==e?M(P("stat"),U):"switch"==e?M(P("form"),D,P("}","switch"),R("{"),G,I,I):"case"==e?M(D,R(":")):"default"==e?M(R(":")):"catch"==e?M(P("form"),E,R("("),re,R(")"),B,I,N):"import"==e?M(K,R(";")):"typedef"==e?M(j):L(P("stat"),D,R(";"),I)}function D(e){return b.hasOwnProperty(e)?M(z):"type"==e?M(z):"function"==e?M(Q):"keyword c"==e?M(F):"("==e?M(P(")"),F,R(")"),I,z):"operator"==e?M(D):"["==e?M(P("]"),$(F,"]"),I,z):"{"==e?M(P("}"),$(q,"}"),I,z):M()}function F(e){return e.match(/[;\}\)\],]/)?L():L(D)}function z(e,t){return"operator"==e&&/\+\+|--/.test(t)?M(z):"operator"==e||":"==e?M(D):";"!=e?"("==e?M(P(")"),$(D,")"),I,z):"."==e?M(V,z):"["==e?M(P("]"),D,R("]"),I,z):void 0:void 0}function W(e){return"attribute"==e?M(W):"function"==e?M(Q):"var"==e?M(X):void 0}function _(e){return":"==e?M(_):"variable"==e?M(_):"("==e?M(P(")"),$(H,")"),I,B):void 0}function H(e){if("variable"==e)return M()}function K(e,t){return"variable"==e&&/[A-Z]/.test(t.charAt(0))?(C(t),M()):"variable"==e||"property"==e||"."==e||"*"==t?M(K):void 0}function j(e,t){return"variable"==e&&/[A-Z]/.test(t.charAt(0))?(C(t),M()):"type"==e&&/[A-Z]/.test(t.charAt(0))?M():void 0}function U(e){return":"==e?M(I,B):L(z,R(";"),I)}function V(e){if("variable"==e)return S.marked="property",M()}function q(e){if("variable"==e&&(S.marked="property"),b.hasOwnProperty(e))return M(R(":"),D)}function $(e,t){function n(r){return","==r?M(e,n):r==t?M():M(R(t))}return function(r){return r==t?M():L(e,n)}}function G(e){return"}"==e?M():L(B,G)}function X(e,t){return"variable"==e?(A(t),M(ee,Y)):M()}function Y(e,t){return"="==t?M(D,Y):","==e?M(X):void 0}function Z(e,t){return"variable"==e?(A(t),M(J,D)):L()}function J(e,t){if("in"==t)return M()}function Q(e,t){return"variable"==e||"type"==e?(A(t),M(Q)):"new"==t?M(Q):"("==e?M(P(")"),E,$(re,")"),I,ee,B,N):void 0}function ee(e){if(":"==e)return M(te)}function te(e){return"type"==e?M():"variable"==e?M():"{"==e?M(P("}"),$(ne,"}"),I):void 0}function ne(e){if("variable"==e)return M(ee)}function re(e,t){if("variable"==e)return A(t),M(ee)}return N.lex=!0,I.lex=!0,{startState:function(e){var r={tokenize:v,reAllowed:!0,kwAllowed:!0,cc:[],lexical:new x((e||0)-n,0,"block",!1),localVars:t.localVars,importedtypes:["Int","Float","String","Void","Std","Bool","Dynamic","Array"],context:t.localVars&&{vars:t.localVars},indented:0};return t.globalVars&&"object"==typeof t.globalVars&&(r.globalVars=t.globalVars),r},token:function(e,t){if(e.sol()&&(t.lexical.hasOwnProperty("align")||(t.lexical.align=!1),t.indented=e.indentation()),e.eatSpace())return null;var n=t.tokenize(e,t);return"comment"==f?n:(t.reAllowed=!("operator"!=f&&"keyword c"!=f&&!f.match(/^[\[{}\(,;:]$/)),t.kwAllowed="."!=f,function(e,t,n,r,i){var o=e.cc;for(S.state=e,S.stream=i,S.marked=null,S.cc=o,e.lexical.hasOwnProperty("align")||(e.lexical.align=!0);;){var a=o.length?o.pop():B;if(a(n,r)){for(;o.length&&o[o.length-1].lex;)o.pop()();return S.marked?S.marked:"variable"==n&&w(e,r)?"variable-2":"variable"==n&&k(e,r)?"variable-3":t}}}(t,n,f,i,e))},indent:function(e,t){if(e.tokenize!=v)return 0;var r=t&&t.charAt(0),i=e.lexical;"stat"==i.type&&"}"==r&&(i=i.prev);var o=i.type,a=r==o;return"vardef"==o?i.indented+4:"form"==o&&"{"==r?i.indented:"stat"==o||"form"==o?i.indented+n:"switch"!=i.info||a?i.align?i.column+(a?0:1):i.indented+(a?0:n):i.indented+(/^(?:case|default)\b/.test(t)?n:2*n)},electricChars:"{}",blockCommentStart:"/*",blockCommentEnd:"*/",lineComment:"//"}}),e.defineMIME("text/x-haxe","haxe"),e.defineMode("hxml",function(){return{startState:function(){return{define:!1,inString:!1}},token:function(e,t){var n=e.peek(),r=e.sol();if("#"==n)return e.skipToEnd(),"comment";if(r&&"-"==n){var i="variable-2";return e.eat(/-/),"-"==e.peek()&&(e.eat(/-/),i="keyword a"),"D"==e.peek()&&(e.eat(/[D]/),i="keyword c",t.define=!0),e.eatWhile(/[A-Z]/i),i}var n=e.peek();return 0==t.inString&&"'"==n&&(t.inString=!0,e.next()),1==t.inString?(e.skipTo("'")||e.skipToEnd(),"'"==e.peek()&&(e.next(),t.inString=!1),"string"):(e.next(),null)},lineComment:"#"}}),e.defineMIME("text/x-hxml","hxml")}(n(0))},function(e,t,n){!function(e){"use strict";var t={},n=/[^\s\u00a0]/,r=e.Pos;function i(e){var t=e.search(n);return-1==t?0:t}function o(e,t){var n=e.getMode();return!1!==n.useInnerComments&&n.innerMode?e.getModeAt(t):n}e.commands.toggleComment=function(e){e.toggleComment()},e.defineExtension("toggleComment",function(e){e||(e=t);for(var n=1/0,i=this.listSelections(),o=null,a=i.length-1;a>=0;a--){var l=i[a].from(),s=i[a].to();l.line>=n||(s.line>=n&&(s=r(n,0)),n=l.line,null==o?this.uncomment(l,s,e)?o="un":(this.lineComment(l,s,e),o="line"):"un"==o?this.uncomment(l,s,e):this.lineComment(l,s,e))}}),e.defineExtension("lineComment",function(e,a,l){l||(l=t);var s=this,c=o(s,e),u=s.getLine(e.line);if(null!=u&&!function(e,t,n){return/\bstring\b/.test(e.getTokenTypeAt(r(t.line,0)))&&!/^[\'\"\`]/.test(n)}(s,e,u)){var f=l.lineComment||c.lineComment;if(f){var d=Math.min(0!=a.ch||a.line==e.line?a.line+1:a.line,s.lastLine()+1),h=null==l.padding?" ":l.padding,p=l.commentBlankLines||e.line==a.line;s.operation(function(){if(l.indent){for(var t=null,o=e.line;oc.length)&&(t=c)}for(var o=e.line;of||l.operation(function(){if(0!=a.fullLines){var t=n.test(l.getLine(f));l.replaceRange(d+u,r(f)),l.replaceRange(c+d,r(e.line,0));var o=a.blockCommentLead||s.blockCommentLead;if(null!=o)for(var h=e.line+1;h<=f;++h)(h!=f||t)&&l.replaceRange(o+d,r(h,0))}else l.replaceRange(u,i),l.replaceRange(c,e)})}}else(a.lineComment||s.lineComment)&&0!=a.fullLines&&l.lineComment(e,i,a)}),e.defineExtension("uncomment",function(e,i,a){a||(a=t);var l,s=this,c=o(s,e),u=Math.min(0!=i.ch||i.line==e.line?i.line:i.line-1,s.lastLine()),f=Math.min(e.line,u),d=a.lineComment||c.lineComment,h=[],p=null==a.padding?" ":a.padding;e:if(d){for(var m=f;m<=u;++m){var g=s.getLine(m),v=g.indexOf(d);if(v>-1&&!/comment/.test(s.getTokenTypeAt(r(m,v+1)))&&(v=-1),-1==v&&n.test(g))break e;if(v>-1&&n.test(g.slice(0,v)))break e;h.push(g)}if(s.operation(function(){for(var e=f;e<=u;++e){var t=h[e-f],n=t.indexOf(d),i=n+d.length;n<0||(t.slice(i,i+p.length)==p&&(i+=p.length),l=!0,s.replaceRange("",r(e,n),r(e,i)))}}),l)return!0}var y=a.blockCommentStart||c.blockCommentStart,b=a.blockCommentEnd||c.blockCommentEnd;if(!y||!b)return!1;var x=a.blockCommentLead||c.blockCommentLead,w=s.getLine(f),k=w.indexOf(y);if(-1==k)return!1;var C=u==f?w:s.getLine(u),S=C.indexOf(b,u==f?k+y.length:0),L=r(f,k+1),M=r(u,S+1);if(-1==S||!/comment/.test(s.getTokenTypeAt(L))||!/comment/.test(s.getTokenTypeAt(M))||s.getRange(L,M,"\n").indexOf(b)>-1)return!1;var T=w.lastIndexOf(y,e.ch),A=-1==T?-1:w.slice(0,e.ch).indexOf(b,T+y.length);if(-1!=T&&-1!=A&&A+b.length!=e.ch)return!1;A=C.indexOf(b,i.ch);var O=C.slice(i.ch).lastIndexOf(y,A-i.ch);return T=-1==A||-1==O?-1:i.ch+O,(-1==A||-1==T||T==i.ch)&&(s.operation(function(){s.replaceRange("",r(u,S-(p&&C.slice(S-p.length,S)==p?p.length:0)),r(u,S+b.length));var e=k+y.length;if(p&&w.slice(e,e+p.length)==p&&(e+=p.length),s.replaceRange("",r(f,k),r(f,e)),x)for(var t=f+1;t<=u;++t){var i=s.getLine(t),o=i.indexOf(x);if(-1!=o&&!n.test(i.slice(0,o))){var a=o+x.length;p&&i.slice(a,a+p.length)==p&&(a+=p.length),s.replaceRange("",r(t,o),r(t,a))}}}),!0)})}(n(0))},function(e,t,n){!function(e){var t={pairs:"()[]{}''\"\"",triples:"",explode:"[]{}"},n=e.Pos;function r(e,n){return"pairs"==n&&"string"==typeof e?e:"object"==typeof e&&null!=e[n]?e[n]:t[n]}e.defineOption("autoCloseBrackets",!1,function(t,n,a){a&&a!=e.Init&&(t.removeKeyMap(i),t.state.closeBrackets=null),n&&(o(r(n,"pairs")),t.state.closeBrackets=n,t.addKeyMap(i))});var i={Backspace:function(t){var i=l(t);if(!i||t.getOption("disableInput"))return e.Pass;for(var o=r(i,"pairs"),a=t.listSelections(),s=0;s=0;s--){var f=a[s].head;t.replaceRange("",n(f.line,f.ch-1),n(f.line,f.ch+1),"+delete")}},Enter:function(t){var n=l(t),i=n&&r(n,"explode");if(!i||t.getOption("disableInput"))return e.Pass;for(var o=t.listSelections(),a=0;a1&&h.indexOf(i)>=0&&t.getRange(n(x.line,x.ch-2),x)==i+i){if(x.ch>2&&/\bstring/.test(t.getTokenTypeAt(n(x.line,x.ch-2))))return e.Pass;y="addFour"}else if(p){var k=0==x.ch?" ":t.getRange(n(x.line,x.ch-1),x);if(e.isWordChar(w)||k==i||e.isWordChar(k))return e.Pass;y="both"}else{if(!g||t.getLine(x.line).length!=x.ch&&!c(w,a)&&!/\s/.test(w))return e.Pass;y="both"}else y=p&&f(t,x)?"both":h.indexOf(i)>=0&&t.getRange(x,n(x.line,x.ch+3))==i+i+i?"skipThree":"skip";if(d){if(d!=y)return e.Pass}else d=y}var C=u%2?a.charAt(u-1):i,S=u%2?i:a.charAt(u+1);t.operation(function(){if("skip"==d)t.execCommand("goCharRight");else if("skipThree"==d)for(var e=0;e<3;e++)t.execCommand("goCharRight");else if("surround"==d){for(var n=t.getSelections(),e=0;e0;return{anchor:new n(t.anchor.line,t.anchor.ch+(r?-1:1)),head:new n(t.head.line,t.head.ch+(r?1:-1))}}function c(e,t){var n=t.lastIndexOf(e);return n>-1&&n%2==1}function u(e,t){var r=e.getRange(n(t.line,t.ch-1),n(t.line,t.ch+1));return 2==r.length?r:null}function f(e,t){var r=e.getTokenAt(n(t.line,t.ch+1));return/\bstring/.test(r.type)&&r.start==t.ch&&(0==t.ch||!/\bstring/.test(e.getTokenTypeAt(t)))}o(t.pairs+"`")}(n(0))},function(e,t,n){!function(e){"use strict";function t(e){return e.state.search||(e.state.search=new function(){this.posFrom=this.posTo=this.lastQuery=this.query=null,this.overlay=null})}function n(e){return"string"==typeof e&&e==e.toLowerCase()}function r(e,t,r){return e.getSearchCursor(t,r,{caseFold:n(t),multiline:!0})}function i(e,t,n,r,i){e.openDialog?e.openDialog(t,i,{value:r,selectValueOnOpen:!0}):i(prompt(n,r))}function o(e){return e.replace(/\\(.)/g,function(e,t){return"n"==t?"\n":"r"==t?"\r":t})}function a(e){var t=e.match(/^\/(.*)\/([a-z]*)$/);if(t)try{e=new RegExp(t[1],-1==t[2].indexOf("i")?"":"i")}catch(e){}else e=o(e);return("string"==typeof e?""==e:e.test(""))&&(e=/x^/),e}var l;function s(e,t,r){t.queryText=r,t.query=a(r),e.removeOverlay(t.overlay,n(t.query)),t.overlay=function(e,t){return"string"==typeof e?e=new RegExp(e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&"),t?"gi":"g"):e.global||(e=new RegExp(e.source,e.ignoreCase?"gi":"g")),{token:function(t){e.lastIndex=t.pos;var n=e.exec(t.string);if(n&&n.index==t.pos)return t.pos+=n[0].length||1,"searching";n?t.pos=n.index:t.skipToEnd()}}}(t.query,n(t.query)),e.addOverlay(t.overlay),e.showMatchesOnScrollbar&&(t.annotate&&(t.annotate.clear(),t.annotate=null),t.annotate=e.showMatchesOnScrollbar(t.query,n(t.query)))}function c(n,r,o,a){if(!l){let e=n.getWrapperElement().ownerDocument,t=e.createElement("input");t.type="search",t.placeholder=n.l10n("findCmd.promptMessage"),t.style.marginInlineStart="1em",t.style.marginInlineEnd="1em",t.style.flexGrow="1",t.addEventListener("focus",()=>t.select()),(l=e.createElement("div")).appendChild(t),l.style.display="flex"}var c=t(n);if(c.query)return u(n,r);var d=n.getSelection()||c.lastQuery;if(d instanceof RegExp&&"x^"==d.source&&(d=null),o&&n.openDialog){var h=null,p=function(t,r){e.e_stop(r),t&&(t!=c.queryText&&(s(n,c,t),c.posFrom=c.posTo=n.getCursor()),h&&(h.style.opacity=1),u(n,r.shiftKey,function(e,t){var r;t.line<3&&document.querySelector&&(r=n.display.wrapper.querySelector(".CodeMirror-dialog"))&&r.getBoundingClientRect().bottom-4>n.cursorCoords(t,"window").top&&((h=r).style.opacity=.4)}))};!function(e,t,n,r,i){e.openDialog(t,r,{value:n,selectValueOnOpen:!0,closeOnEnter:!1,onClose:function(){f(e)},onKeyDown:i})}(n,l,d,p,function(r,i){var o=e.keyName(r),a=n.getOption("extraKeys"),l=a&&a[o]||e.keyMap[n.getOption("keyMap")][o];"findNext"==l||"findPrev"==l||"findPersistentNext"==l||"findPersistentPrev"==l?(e.e_stop(r),s(n,t(n),i),n.execCommand(l)):"find"!=l&&"findPersistent"!=l||(e.e_stop(r),p(i,r))}),a&&d&&(s(n,c,d),u(n,r))}else i(n,l,"Search for:",d,function(e){e&&!c.query&&n.operation(function(){s(n,c,e),c.posFrom=c.posTo=n.getCursor(),u(n,r)})})}function u(n,i,o){n.operation(function(){var a=t(n),l=r(n,a.query,i?a.posFrom:a.posTo);(l.find(i)||(l=r(n,a.query,i?e.Pos(n.lastLine()):e.Pos(n.firstLine(),0))).find(i))&&(n.setSelection(l.from(),l.to()),n.scrollIntoView({from:l.from(),to:l.to()},20),a.posFrom=l.from(),a.posTo=l.to(),o&&o(l.from(),l.to()))})}function f(e){e.operation(function(){var n=t(e);n.lastQuery=n.query,n.query&&(n.query=n.queryText=null,e.removeOverlay(n.overlay),n.annotate&&(n.annotate.clear(),n.annotate=null))})}function d(e,t,n){e.operation(function(){for(var i=r(e,t);i.findNext();)if("string"!=typeof t){var o=e.getRange(i.from(),i.to()).match(t);i.replace(n.replace(/\$(\d)/g,function(e,t){return o[t]}))}else i.replace(n)})}function h(e,n){if(e.getOption("readOnly"))return;var l=e.getSelection()||t(e).lastQuery;let s=e.getWrapperElement().ownerDocument,c=s.createElement("span");c.classList.add("CodeMirror-search-label"),c.textContent=n?"Replace all:":"Replace:";let u=s.createDocumentFragment();u.appendChild(c.cloneNode(!0));let h=s.createElement("input");h.setAttribute("type","text"),h.setAttribute("style","width: 10em"),h.classList.add("CodeMirror-search-field"),u.appendChild(h);let p=s.createElement("span");p.setAttribute("style","color: #888"),p.classList.add("CodeMirror-search-hint"),p.textContent="(Use /re/ syntax for regexp search)",u.appendChild(p),i(e,u,c,l,function(t){if(!t)return;t=a(t);let l=s.createDocumentFragment(),u=c.cloneNode(!1);u.textContent="With:",l.appendChild(u);let h=s.createElement("input");h.setAttribute("type","text"),h.setAttribute("style","width: 10em"),h.classList.add("CodeMirror-search-field"),l.appendChild(h),i(e,l,"Replace with:","",function(i){if(i=o(i),n)d(e,t,i);else{f(e);var a=r(e,t,e.getCursor("from")),l=function(){var n,o=a.from();if(!(n=a.findNext())&&(a=r(e,t),!(n=a.findNext())||o&&a.from().line==o.line&&a.from().ch==o.ch))return;e.setSelection(a.from(),a.to()),e.scrollIntoView({from:a.from(),to:a.to()});let f=s.createDocumentFragment(),h=c.cloneNode(!1);h.textContent="Replace?",f.appendChild(h);let p=s.createElement("button");p.textContent="Yes",f.appendChild(p);let m=s.createElement("button");m.textContent="No",f.appendChild(m);let g=s.createElement("button");g.textContent="All",f.appendChild(g);let v=s.createElement("button");v.textContent="Stop",f.appendChild(v),function(e,t,n,r){e.openConfirm?e.openConfirm(t,r):confirm(n)&&r[0]()}(e,f,"Replace?",[function(){u(n)},l,function(){d(e,t,i)}])},u=function(e){a.replace("string"==typeof t?i:i.replace(/\$(\d)/g,function(t,n){return e[n]})),l()};l()}})})}e.commands.find=function(e){f(e),c(e)},e.commands.findPersistent=function(e){f(e),c(e,!1,!0)},e.commands.findPersistentNext=function(e){c(e,!1,!0,!0)},e.commands.findPersistentPrev=function(e){c(e,!0,!0,!0)},e.commands.findNext=c,e.commands.findPrev=function(e){c(e,!0)},e.commands.clearSearch=f,e.commands.replace=h,e.commands.replaceAll=function(e){h(e,!0)}}(n(0),n(1),n(5))},function(e,t,n){n(5),n(1),n(27),n(4),n(26),n(25),n(3),n(2),n(7),n(24),n(23),n(22),n(21),n(20),n(19),n(18),n(17),n(16),n(15),n(14),n(13),n(6),n(12),n(11),n(10),n(9),n(8),e.exports=n(0)}]); \ No newline at end of file diff --git a/devtools/client/sourceeditor/codemirror/lib/codemirror.js b/devtools/client/sourceeditor/codemirror/lib/codemirror.js index 5f645466979d..487974a9da98 100644 --- a/devtools/client/sourceeditor/codemirror/lib/codemirror.js +++ b/devtools/client/sourceeditor/codemirror/lib/codemirror.js @@ -6577,8 +6577,6 @@ function registerGlobalHandlers() { // Called when the window resizes function onResize(cm) { var d = cm.display - if (d.lastWrapHeight == d.wrapper.clientHeight && d.lastWrapWidth == d.wrapper.clientWidth) - { return } // Might be a text scaling operation, clear size caches. d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null d.scrollbarsClipped = false @@ -9678,7 +9676,7 @@ CodeMirror.fromTextArea = fromTextArea addLegacyProps(CodeMirror) -CodeMirror.version = "5.38.0" +CodeMirror.version = "5.39.0" return CodeMirror; diff --git a/devtools/client/sourceeditor/codemirror/mode/javascript/javascript.js b/devtools/client/sourceeditor/codemirror/mode/javascript/javascript.js index 097c0bbe6d66..ba27c5d0bc00 100644 --- a/devtools/client/sourceeditor/codemirror/mode/javascript/javascript.js +++ b/devtools/client/sourceeditor/codemirror/mode/javascript/javascript.js @@ -344,7 +344,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) { function expect(wanted) { function exp(type) { if (type == wanted) return cont(); - else if (wanted == ";") return pass(); + else if (wanted == ";" || type == "}" || type == ")" || type == "]") return pass(); else return cont(exp); }; return exp; diff --git a/devtools/client/sourceeditor/codemirror/mode/xml/xml.js b/devtools/client/sourceeditor/codemirror/mode/xml/xml.js index 0f1c9b175ef7..5927bc917bf6 100644 --- a/devtools/client/sourceeditor/codemirror/mode/xml/xml.js +++ b/devtools/client/sourceeditor/codemirror/mode/xml/xml.js @@ -163,8 +163,9 @@ CodeMirror.defineMode("xml", function(editorConf, config_) { stream.next(); } return style; - }; + } } + function doctype(depth) { return function(stream, state) { var ch; diff --git a/docshell/base/nsDocShellTreeOwner.cpp b/docshell/base/nsDocShellTreeOwner.cpp index 8f1418c57f38..c633a329392b 100644 --- a/docshell/base/nsDocShellTreeOwner.cpp +++ b/docshell/base/nsDocShellTreeOwner.cpp @@ -1218,7 +1218,7 @@ ChromeTooltipListener::MouseMove(Event* aMouseEvent) if (!mShowingTooltip && !mTooltipShownOnce) { nsIEventTarget* target = nullptr; - nsCOMPtr eventTarget = aMouseEvent->GetTarget(); + nsCOMPtr eventTarget = aMouseEvent->GetComposedTarget(); if (eventTarget) { mPossibleTooltipNode = do_QueryInterface(eventTarget); nsCOMPtr global(eventTarget->GetOwnerGlobal()); @@ -1317,6 +1317,12 @@ ChromeTooltipListener::sTooltipCallback(nsITimer* aTimer, { auto self = static_cast(aChromeTooltipListener); if (self && self->mPossibleTooltipNode) { + if (!self->mPossibleTooltipNode->IsInComposedDoc()) { + // release tooltip target if there is one, NO MATTER WHAT + self->mPossibleTooltipNode = nullptr; + return; + } + // The actual coordinates we want to put the tooltip at are relative to the // toplevel docshell of our mWebBrowser. We know what the screen // coordinates of the mouse event were, which means we just need the screen diff --git a/dom/base/nsDocument.cpp b/dom/base/nsDocument.cpp index b850afead3d9..5dbb73528e8d 100644 --- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -2612,6 +2612,21 @@ nsDocument::IsShadowDOMEnabled(JSContext* aCx, JSObject* aGlobal) return doc->IsShadowDOMEnabled(); } +// static +bool +nsDocument::IsShadowDOMEnabledAndCallerIsChromeOrAddon(JSContext* aCx, + JSObject* aObject) +{ + if (IsShadowDOMEnabled(aCx, aObject)) { + nsIPrincipal* principal = nsContentUtils::SubjectPrincipal(aCx); + return principal && + (nsContentUtils::IsSystemPrincipal(principal) || + principal->GetIsAddonOrExpandedAddonPrincipal()); + } + + return false; +} + bool nsDocument::IsShadowDOMEnabled(const nsINode* aNode) { diff --git a/dom/base/nsDocument.h b/dom/base/nsDocument.h index 9c45e72fee0a..32732fa2000b 100644 --- a/dom/base/nsDocument.h +++ b/dom/base/nsDocument.h @@ -196,6 +196,8 @@ public: // Check whether shadow DOM is enabled for aGlobal. static bool IsShadowDOMEnabled(JSContext* aCx, JSObject* aGlobal); // Check whether shadow DOM is enabled for the document this node belongs to. + // Same as above, but also checks that the caller is either chrome or some addon. + static bool IsShadowDOMEnabledAndCallerIsChromeOrAddon(JSContext* aCx, JSObject* aObject); static bool IsShadowDOMEnabled(const nsINode* aNode); public: diff --git a/dom/base/nsGlobalWindowInner.cpp b/dom/base/nsGlobalWindowInner.cpp index a3e3151bc0eb..1ed50294776b 100644 --- a/dom/base/nsGlobalWindowInner.cpp +++ b/dom/base/nsGlobalWindowInner.cpp @@ -111,7 +111,6 @@ #include "nsIDocShell.h" #include "nsIDocument.h" #include "Crypto.h" -#include "nsIDOMOfflineResourceList.h" #include "nsDOMString.h" #include "nsIEmbeddingSiteWindow.h" #include "nsThreadUtils.h" @@ -3134,7 +3133,7 @@ nsGlobalWindowInner::DeviceSensorsEnabled(JSContext* aCx, JSObject* aObj) return Preferences::GetBool("device.sensors.enabled"); } -nsIDOMOfflineResourceList* +nsDOMOfflineResourceList* nsGlobalWindowInner::GetApplicationCache(ErrorResult& aError) { if (!mApplicationCache) { @@ -3165,14 +3164,10 @@ nsGlobalWindowInner::GetApplicationCache(ErrorResult& aError) return mApplicationCache; } -already_AddRefed +nsDOMOfflineResourceList* nsGlobalWindowInner::GetApplicationCache() { - ErrorResult dummy; - nsCOMPtr applicationCache = - GetApplicationCache(dummy); - dummy.SuppressException(); - return applicationCache.forget(); + return GetApplicationCache(IgnoreErrors()); } Crypto* @@ -5886,8 +5881,7 @@ nsGlobalWindowInner::Observe(nsISupports* aSubject, const char* aTopic, // Instantiate the application object now. It observes update belonging to // this window's document and correctly updates the applicationCache object // state. - nsCOMPtr applicationCache = GetApplicationCache(); - nsCOMPtr observer = do_QueryInterface(applicationCache); + nsCOMPtr observer = GetApplicationCache(); if (observer) observer->Observe(aSubject, aTopic, aData); diff --git a/dom/base/nsGlobalWindowInner.h b/dom/base/nsGlobalWindowInner.h index 39c3e9863163..9d1a4bfb9df9 100644 --- a/dom/base/nsGlobalWindowInner.h +++ b/dom/base/nsGlobalWindowInner.h @@ -64,7 +64,7 @@ class nsIBaseWindow; class nsIContent; class nsICSSDeclaration; class nsIDocShellTreeOwner; -class nsIDOMOfflineResourceList; +class nsDOMOfflineResourceList; class nsIScrollableFrame; class nsIControllers; class nsIJSID; @@ -684,8 +684,8 @@ public: const nsAString& aName, const nsAString& aOptions, mozilla::ErrorResult& aError); - nsIDOMOfflineResourceList* GetApplicationCache(mozilla::ErrorResult& aError); - already_AddRefed GetApplicationCache() override; + nsDOMOfflineResourceList* GetApplicationCache(mozilla::ErrorResult& aError); + nsDOMOfflineResourceList* GetApplicationCache() override; #if defined(MOZ_WIDGET_ANDROID) int16_t Orientation(mozilla::dom::CallerType aCallerType) const; @@ -1420,7 +1420,7 @@ protected: nsCOMPtr mLastOpenedURI; #endif - nsCOMPtr mApplicationCache; + RefPtr mApplicationCache; using XBLPrototypeHandlerTable = nsJSThingHashtable, JSObject*>; mozilla::UniquePtr mCachedXBLPrototypeHandlers; diff --git a/dom/base/nsGlobalWindowOuter.cpp b/dom/base/nsGlobalWindowOuter.cpp index b43535b84eb5..96bc61181190 100644 --- a/dom/base/nsGlobalWindowOuter.cpp +++ b/dom/base/nsGlobalWindowOuter.cpp @@ -34,7 +34,6 @@ #if defined(MOZ_WIDGET_ANDROID) #include "mozilla/dom/WindowOrientationObserver.h" #endif -#include "nsDOMOfflineResourceList.h" #include "nsError.h" #include "nsIIdleService.h" #include "nsISizeOfEventTarget.h" @@ -108,7 +107,6 @@ #include "nsIDocShell.h" #include "nsIDocument.h" #include "Crypto.h" -#include "nsIDOMOfflineResourceList.h" #include "nsDOMString.h" #include "nsIEmbeddingSiteWindow.h" #include "nsThreadUtils.h" diff --git a/dom/base/nsGlobalWindowOuter.h b/dom/base/nsGlobalWindowOuter.h index a4fcd0e5fb9b..286300ebb0b0 100644 --- a/dom/base/nsGlobalWindowOuter.h +++ b/dom/base/nsGlobalWindowOuter.h @@ -61,7 +61,6 @@ class nsIBaseWindow; class nsIContent; class nsICSSDeclaration; class nsIDocShellTreeOwner; -class nsIDOMOfflineResourceList; class nsIScrollableFrame; class nsIControllers; class nsIJSID; diff --git a/dom/base/nsPIDOMWindow.h b/dom/base/nsPIDOMWindow.h index 5b6864e171d2..14c0ee3efe0e 100644 --- a/dom/base/nsPIDOMWindow.h +++ b/dom/base/nsPIDOMWindow.h @@ -22,6 +22,7 @@ #define DOM_WINDOW_FROZEN_TOPIC "dom-window-frozen" #define DOM_WINDOW_THAWED_TOPIC "dom-window-thawed" +class nsDOMOfflineResourceList; class nsDOMWindowList; class nsGlobalWindowInner; class nsGlobalWindowOuter; @@ -614,7 +615,7 @@ public: virtual mozilla::dom::Element* GetFrameElement() = 0; - virtual already_AddRefed GetApplicationCache() = 0; + virtual nsDOMOfflineResourceList* GetApplicationCache() = 0; virtual bool GetFullScreen() = 0; diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index 59dc95076608..b20da80c1be4 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -1817,7 +1817,6 @@ def addExternalIface(iface, nativeType=None, headerFile=None, domInterface['notflattened'] = notflattened DOMInterfaces[iface] = domInterface -addExternalIface('ApplicationCache', nativeType='nsIDOMOfflineResourceList') addExternalIface('Cookie', nativeType='nsICookie2', headerFile='nsICookie2.h', notflattened=True) addExternalIface('HitRegionOptions', nativeType='nsISupports') diff --git a/dom/interfaces/base/nsIDOMWindow.idl b/dom/interfaces/base/nsIDOMWindow.idl index 196fe322982e..71a626e01659 100644 --- a/dom/interfaces/base/nsIDOMWindow.idl +++ b/dom/interfaces/base/nsIDOMWindow.idl @@ -6,7 +6,6 @@ #include "domstubs.idl" interface nsIControllers; -interface nsIDOMOfflineResourceList; interface nsIPrompt; interface nsIVariant; diff --git a/dom/interfaces/offline/moz.build b/dom/interfaces/offline/moz.build deleted file mode 100644 index ef464caf6fc2..000000000000 --- a/dom/interfaces/offline/moz.build +++ /dev/null @@ -1,15 +0,0 @@ -# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- -# vim: set filetype=python: -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -with Files("**"): - BUG_COMPONENT = ("Core", "DOM") - -XPIDL_SOURCES += [ - 'nsIDOMOfflineResourceList.idl', -] - -XPIDL_MODULE = 'dom_offline' - diff --git a/dom/interfaces/offline/nsIDOMOfflineResourceList.idl b/dom/interfaces/offline/nsIDOMOfflineResourceList.idl deleted file mode 100644 index 0189be16139d..000000000000 --- a/dom/interfaces/offline/nsIDOMOfflineResourceList.idl +++ /dev/null @@ -1,91 +0,0 @@ -/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "domstubs.idl" - -[shim(OfflineResourceList), uuid(6044702d-e4a9-420c-b711-558b7d6a3b9f)] -interface nsIDOMOfflineResourceList : nsISupports -{ - /** - * Get the list of dynamically-managed entries. - */ - readonly attribute nsISupports mozItems; - - /** - * Check that an entry exists in the list of dynamically-managed entries. - * - * @param uri - * The resource to check. - */ - boolean mozHasItem(in DOMString uri); - - /** - * Get the number of dynamically-managed entries. - * @status DEPRECATED - * Clients should use the "items" attribute. - */ - readonly attribute unsigned long mozLength; - - /** - * Get the URI of a dynamically-managed entry. - * @status DEPRECATED - * Clients should use the "items" attribute. - */ - DOMString mozItem(in unsigned long index); - - /** - * Add an item to the list of dynamically-managed entries. The resource - * will be fetched into the application cache. - * - * @param uri - * The resource to add. - */ - void mozAdd(in DOMString uri); - - /** - * Remove an item from the list of dynamically-managed entries. If this - * was the last reference to a URI in the application cache, the cache - * entry will be removed. - * - * @param uri - * The resource to remove. - */ - void mozRemove(in DOMString uri); - - /** - * State of the application cache this object is associated with. - */ - - /* This object is not associated with an application cache. */ - const unsigned short UNCACHED = 0; - - /* The application cache is not being updated. */ - const unsigned short IDLE = 1; - - /* The manifest is being fetched and checked for updates */ - const unsigned short CHECKING = 2; - - /* Resources are being downloaded to be added to the cache */ - const unsigned short DOWNLOADING = 3; - - /* There is a new version of the application cache available */ - const unsigned short UPDATEREADY = 4; - - /* The application cache group is now obsolete. */ - const unsigned short OBSOLETE = 5; - - readonly attribute unsigned short status; - - /** - * Begin the application update process on the associated application cache. - */ - void update(); - - /** - * Swap in the newest version of the application cache, or disassociate - * from the cache if the cache group is obsolete. - */ - void swapCache(); -}; diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index a6f3ae0dc237..0ddc2fffe673 100644 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -2026,6 +2026,9 @@ ContentParent::LaunchSubprocess(ProcessPriority aInitialPriority /* = PROCESS_PR // Prefs information is passed via anonymous shared memory to avoid bloating // the command line. + size_t prefMapSize; + auto prefMapHandle = Preferences::EnsureSnapshot(&prefMapSize).ClonePlatformHandle(); + // Serialize the early prefs. nsAutoCStringN<1024> prefs; Preferences::SerializePreferences(prefs); @@ -2046,14 +2049,22 @@ ContentParent::LaunchSubprocess(ProcessPriority aInitialPriority /* = PROCESS_PR // Copy the serialized prefs into the shared memory. memcpy(static_cast(shm.memory()), prefs.get(), prefs.Length()); + // Formats a pointer or pointer-sized-integer as a string suitable for passing + // in an arguments list. + auto formatPtrArg = [] (auto arg) { + return nsPrintfCString("%zu", uintptr_t(arg)); + }; + #if defined(XP_WIN) // Record the handle as to-be-shared, and pass it via a command flag. This // works because Windows handles are system-wide. HANDLE prefsHandle = shm.handle(); mSubprocess->AddHandleToShare(prefsHandle); + mSubprocess->AddHandleToShare(prefMapHandle.get()); extraArgs.push_back("-prefsHandle"); - extraArgs.push_back( - nsPrintfCString("%zu", reinterpret_cast(prefsHandle)).get()); + extraArgs.push_back(formatPtrArg(prefsHandle).get()); + extraArgs.push_back("-prefMapHandle"); + extraArgs.push_back(formatPtrArg(prefMapHandle.get()).get()); #else // In contrast, Unix fds are per-process. So remap the fd to a fixed one that // will be used in the child. @@ -2063,11 +2074,15 @@ ContentParent::LaunchSubprocess(ProcessPriority aInitialPriority /* = PROCESS_PR // and the fixed fd isn't used. However, we still need to mark it for // remapping so it doesn't get closed in the child. mSubprocess->AddFdToRemap(shm.handle().fd, kPrefsFileDescriptor); + mSubprocess->AddFdToRemap(prefMapHandle.get(), kPrefMapFileDescriptor); #endif - // Pass the length via a command flag. + // Pass the lengths via command line flags. extraArgs.push_back("-prefsLen"); - extraArgs.push_back(nsPrintfCString("%zu", uintptr_t(prefs.Length())).get()); + extraArgs.push_back(formatPtrArg(prefs.Length()).get()); + + extraArgs.push_back("-prefMapSize"); + extraArgs.push_back(formatPtrArg(prefMapSize).get()); // Scheduler prefs need to be handled differently because the scheduler needs // to start up in the content process before the normal preferences service. @@ -2906,9 +2921,12 @@ ContentParent::Observe(nsISupports* aSubject, BLACKLIST_ENTRY(u"app.update.lastUpdateTime."), BLACKLIST_ENTRY(u"datareporting.policy."), BLACKLIST_ENTRY(u"browser.safebrowsing.provider."), + BLACKLIST_ENTRY(u"browser.shell."), + BLACKLIST_ENTRY(u"browser.slowstartup."), BLACKLIST_ENTRY(u"extensions.getAddons.cache."), BLACKLIST_ENTRY(u"media.gmp-manager."), BLACKLIST_ENTRY(u"media.gmp-gmpopenh264."), + BLACKLIST_ENTRY(u"privacy.sanitize."), }; #undef BLACKLIST_ENTRY diff --git a/dom/ipc/ContentProcess.cpp b/dom/ipc/ContentProcess.cpp index a2750a9c77d8..924ebd0a1218 100644 --- a/dom/ipc/ContentProcess.cpp +++ b/dom/ipc/ContentProcess.cpp @@ -83,12 +83,19 @@ SetUpSandboxEnvironment() #ifdef ANDROID static int gPrefsFd = -1; +static int gPrefMapFd = -1; void SetPrefsFd(int aFd) { gPrefsFd = aFd; } + +void +SetPrefMapFd(int aFd) +{ + gPrefMapFd = aFd; +} #endif bool @@ -97,13 +104,29 @@ ContentProcess::Init(int aArgc, char* aArgv[]) Maybe childID; Maybe isForBrowser; Maybe prefsHandle; + Maybe prefMapHandle; Maybe prefsLen; + Maybe prefMapSize; Maybe schedulerPrefs; Maybe parentBuildID; #if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX) nsCOMPtr profileDir; #endif + // Parses an arg containing a pointer-sized-integer. + auto parseUIntPtrArg = [] (char*& aArg) { + // ContentParent uses %zu to print a word-sized unsigned integer. So + // even though strtoull() returns a long long int, it will fit in a + // uintptr_t. + return uintptr_t(strtoull(aArg, &aArg, 10)); + }; + +#ifdef XP_WIN + auto parseHandleArg = [&] (char*& aArg) { + return HANDLE(parseUIntPtrArg(aArg)); + }; +#endif + for (int i = 1; i < aArgc; i++) { if (!aArgv[i]) { continue; @@ -137,11 +160,22 @@ ContentProcess::Init(int aArgc, char* aArgv[]) if (++i == aArgc) { return false; } - // ContentParent uses %zu to print a word-sized unsigned integer. So - // even though strtoull() returns a long long int, it will fit in a - // uintptr_t. char* str = aArgv[i]; - prefsHandle = Some(reinterpret_cast(strtoull(str, &str, 10))); + prefsHandle = Some(parseHandleArg(str)); + if (str[0] != '\0') { + return false; + } + + } else if (strcmp(aArgv[i], "-prefMapHandle") == 0) { + if (++i == aArgc) { + return false; + } + char* str = aArgv[i]; + // The FileDescriptor constructor will clone this handle when constructed, + // so store it in a UniquePlatformHandle to make sure the original gets + // closed. + FileDescriptor::UniquePlatformHandle handle(parseHandleArg(str)); + prefMapHandle.emplace(handle.get()); if (str[0] != '\0') { return false; } @@ -151,11 +185,18 @@ ContentProcess::Init(int aArgc, char* aArgv[]) if (++i == aArgc) { return false; } - // ContentParent uses %zu to print a word-sized unsigned integer. So - // even though strtoull() returns a long long int, it will fit in a - // uintptr_t. char* str = aArgv[i]; - prefsLen = Some(strtoull(str, &str, 10)); + prefsLen = Some(parseUIntPtrArg(str)); + if (str[0] != '\0') { + return false; + } + + } else if (strcmp(aArgv[i], "-prefMapSize") == 0) { + if (++i == aArgc) { + return false; + } + char* str = aArgv[i]; + prefMapSize = Some(parseUIntPtrArg(str)); if (str[0] != '\0') { return false; } @@ -194,9 +235,18 @@ ContentProcess::Init(int aArgc, char* aArgv[]) // Android is different; get the FD via gPrefsFd instead of a fixed fd. MOZ_RELEASE_ASSERT(gPrefsFd != -1); prefsHandle = Some(base::FileDescriptor(gPrefsFd, /* auto_close */ true)); + + FileDescriptor::UniquePlatformHandle handle(gPrefMapFd); + prefMapHandle.emplace(handle.get()); #elif XP_UNIX prefsHandle = Some(base::FileDescriptor(kPrefsFileDescriptor, /* auto_close */ true)); + + // The FileDescriptor constructor will clone this handle when constructed, + // so store it in a UniquePlatformHandle to make sure the original gets + // closed. + FileDescriptor::UniquePlatformHandle handle(kPrefMapFileDescriptor); + prefMapHandle.emplace(handle.get()); #endif // Did we find all the mandatory flags? @@ -204,11 +254,17 @@ ContentProcess::Init(int aArgc, char* aArgv[]) isForBrowser.isNothing() || prefsHandle.isNothing() || prefsLen.isNothing() || + prefMapHandle.isNothing() || + prefMapSize.isNothing() || schedulerPrefs.isNothing() || parentBuildID.isNothing()) { return false; } + // Init the shared-memory base preference mapping first, so that only changed + // preferences wind up in heap memory. + Preferences::InitSnapshot(prefMapHandle.ref(), *prefMapSize); + // Set up early prefs from the shared memory. base::SharedMemory shm; if (!shm.SetHandle(*prefsHandle, /* read_only */ true)) { diff --git a/dom/ipc/ContentProcess.h b/dom/ipc/ContentProcess.h index 6582c94da496..8ec1b5174048 100644 --- a/dom/ipc/ContentProcess.h +++ b/dom/ipc/ContentProcess.h @@ -50,8 +50,10 @@ private: }; #ifdef ANDROID -// Android doesn't use -prefsHandle, it gets that FD another way. +// Android doesn't use -prefsHandle or -prefMapHandle. It gets those FDs +// another way. void SetPrefsFd(int aFd); +void SetPrefMapFd(int aFd); #endif } // namespace dom diff --git a/dom/ipc/MemMapSnapshot.h b/dom/ipc/MemMapSnapshot.h index d29e9748fafc..2771f9f1b7b1 100644 --- a/dom/ipc/MemMapSnapshot.h +++ b/dom/ipc/MemMapSnapshot.h @@ -7,7 +7,7 @@ #ifndef dom_ipc_MemMapSnapshot_h #define dom_ipc_MemMapSnapshot_h -#include "AutoMemMap.h" +#include "mozilla/AutoMemMap.h" #include "mozilla/Attributes.h" #include "mozilla/Maybe.h" #include "mozilla/RangedPtr.h" diff --git a/dom/ipc/SharedStringMap.cpp b/dom/ipc/SharedStringMap.cpp index 69d587cfb109..a3de27ad75d5 100644 --- a/dom/ipc/SharedStringMap.cpp +++ b/dom/ipc/SharedStringMap.cpp @@ -90,8 +90,7 @@ SharedStringMap::Find(const nsCString& aKey, size_t* aIndex) void SharedStringMapBuilder::Add(const nsCString& aKey, const nsString& aValue) { - mEntries.Put(aKey, {{mKeyTable.Add(aKey), aKey.Length()}, - {mValueTable.Add(aValue), aValue.Length()}}); + mEntries.Put(aKey, {mKeyTable.Add(aKey), mValueTable.Add(aValue)}); } Result diff --git a/dom/ipc/SharedStringMap.h b/dom/ipc/SharedStringMap.h index c036f7d12fdb..ab1db7bf9fa1 100644 --- a/dom/ipc/SharedStringMap.h +++ b/dom/ipc/SharedStringMap.h @@ -9,7 +9,7 @@ #include "mozilla/AutoMemMap.h" #include "mozilla/Result.h" -#include "mozilla/TypeTraits.h" +#include "mozilla/dom/ipc/StringTable.h" #include "nsDataHashtable.h" namespace mozilla { @@ -75,25 +75,15 @@ public: size_t mValueStringsSize; }; - /** - * Contains the character offset and character length of an entry in a string - * table. This may be used for either 8-bit or 16-bit strings, and is required - * to retrieve an entry from a string table. - */ - struct StringEntry { - uint32_t mOffset; - uint32_t mLength; - }; - /** * Describes a value in the string map, as offsets into the key and value * string tables. */ struct Entry { // The offset and size of the entry's UTF-8 key in the key string table. - StringEntry mKey; + StringTableEntry mKey; // The offset and size of the entry's UTF-16 value in the value string table. - StringEntry mValue; + StringTableEntry mValue; }; NS_INLINE_DECL_REFCOUNTING(SharedStringMap) @@ -174,35 +164,6 @@ protected: ~SharedStringMap() = default; private: - template - class StringTable - { - using ElemType = decltype(DeclVal()[0]); - - public: - MOZ_IMPLICIT StringTable(const RangedPtr& aBuffer) - : mBuffer(aBuffer.ReinterpretCast()) - { - MOZ_ASSERT(uintptr_t(aBuffer.get()) % alignof(ElemType) == 0, - "Got misalinged buffer"); - } - - StringType Get(const StringEntry& aEntry) const - { - StringType res; - res.AssignLiteral(GetBare(aEntry), aEntry.mLength); - return res; - } - - const ElemType* GetBare(const StringEntry& aEntry) const - { - return &mBuffer[aEntry.mOffset]; - } - - private: - RangedPtr mBuffer; - }; - // Type-safe getters for values in the shared memory region: const Header& GetHeader() const @@ -262,52 +223,6 @@ public: Result Finalize(loader::AutoMemMap& aMap); private: - template - class StringTableBuilder - { - public: - using ElemType = typename StringType::char_type; - - uint32_t Add(const StringType& aKey) - { - auto entry = mEntries.LookupForAdd(aKey).OrInsert([&] () { - Entry newEntry { mSize, aKey }; - mSize += aKey.Length() + 1; - - return newEntry; - }); - - return entry.mOffset; - } - - void Write(const RangedPtr& aBuffer) - { - auto buffer = aBuffer.ReinterpretCast(); - - for (auto iter = mEntries.Iter(); !iter.Done(); iter.Next()) { - auto& entry = iter.Data(); - memcpy(&buffer[entry.mOffset], entry.mValue.BeginReading(), - sizeof(ElemType) * (entry.mValue.Length() + 1)); - } - } - - uint32_t Count() const { return mEntries.Count(); } - - uint32_t Size() const { return mSize * sizeof(ElemType); } - - void Clear() { mEntries.Clear(); } - - private: - struct Entry - { - uint32_t mOffset; - StringType mValue; - }; - - nsDataHashtable mEntries; - uint32_t mSize = 0; - }; - using Entry = SharedStringMap::Entry; StringTableBuilder mKeyTable; diff --git a/dom/ipc/StringTable.h b/dom/ipc/StringTable.h new file mode 100644 index 000000000000..1c626d403cb9 --- /dev/null +++ b/dom/ipc/StringTable.h @@ -0,0 +1,127 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* vim: set ts=8 sts=4 et sw=4 tw=99: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef dom_ipc_StringTable_h +#define dom_ipc_StringTable_h + +#include "mozilla/RangedPtr.h" +#include "nsDataHashtable.h" + +/** + * This file contains helper classes for creating and accessing compact string + * tables, which can be used as the building blocks of shared memory databases. + * Each string table a de-duplicated set of strings which can be referenced + * using their character offsets within a data block and their lengths. The + * string tables, once created, cannot be modified, and are primarily useful in + * read-only shared memory or memory mapped files. + */ + +namespace mozilla { +namespace dom { +namespace ipc { + +/** + * Contains the character offset and character length of an entry in a string + * table. This may be used for either 8-bit or 16-bit strings, and is required + * to retrieve an entry from a string table. + */ +struct StringTableEntry +{ + uint32_t mOffset; + uint32_t mLength; + + // Ignore mLength. It must be the same for any two strings with the same + // offset. + uint32_t Hash() const { return mOffset; } + + bool operator==(const StringTableEntry& aOther) const + { + return mOffset == aOther.mOffset; + } +}; + +template +class StringTable +{ + using ElemType = typename StringType::char_type; + +public: + MOZ_IMPLICIT StringTable(const RangedPtr& aBuffer) + : mBuffer(aBuffer.ReinterpretCast()) + { + MOZ_ASSERT(uintptr_t(aBuffer.get()) % alignof(ElemType) == 0, + "Got misalinged buffer"); + } + + StringType Get(const StringTableEntry& aEntry) const + { + StringType res; + res.AssignLiteral(GetBare(aEntry), aEntry.mLength); + return res; + } + + const ElemType* GetBare(const StringTableEntry& aEntry) const + { + return &mBuffer[aEntry.mOffset]; + } + +private: + RangedPtr mBuffer; +}; + +template +class StringTableBuilder +{ +public: + using ElemType = typename StringType::char_type; + + StringTableEntry Add(const StringType& aKey) + { + const auto& entry = mEntries.LookupForAdd(aKey).OrInsert([&] () { + Entry newEntry { mSize, aKey }; + mSize += aKey.Length() + 1; + + return newEntry; + }); + + return { entry.mOffset, aKey.Length() }; + } + + void Write(const RangedPtr& aBuffer) + { + auto buffer = aBuffer.ReinterpretCast(); + + for (auto iter = mEntries.Iter(); !iter.Done(); iter.Next()) { + auto& entry = iter.Data(); + memcpy(&buffer[entry.mOffset], entry.mValue.BeginReading(), + sizeof(ElemType) * (entry.mValue.Length() + 1)); + } + } + + uint32_t Count() const { return mEntries.Count(); } + + uint32_t Size() const { return mSize * sizeof(ElemType); } + + void Clear() { mEntries.Clear(); } + + static constexpr size_t Alignment() { return alignof(ElemType); } + +private: + struct Entry + { + uint32_t mOffset; + StringType mValue; + }; + + nsDataHashtable mEntries; + uint32_t mSize = 0; +}; + +} // namespace ipc +} // namespace dom +} // namespace mozilla + +#endif diff --git a/dom/ipc/moz.build b/dom/ipc/moz.build index 13f64017a1bb..571db32b19ec 100644 --- a/dom/ipc/moz.build +++ b/dom/ipc/moz.build @@ -15,9 +15,11 @@ XPIDL_MODULE = 'dom' EXPORTS.mozilla.dom.ipc += [ 'IdType.h', + 'MemMapSnapshot.h', 'SharedMap.h', 'SharedMapChangeEvent.h', 'SharedStringMap.h', + 'StringTable.h', 'StructuredCloneData.h', ] diff --git a/dom/moz.build b/dom/moz.build index e0a02b07ba90..ddd35ddc6ed1 100644 --- a/dom/moz.build +++ b/dom/moz.build @@ -21,7 +21,6 @@ interfaces = [ 'xul', 'security', 'storage', - 'offline', 'geolocation', 'notification', 'push', diff --git a/dom/offline/nsDOMOfflineResourceList.cpp b/dom/offline/nsDOMOfflineResourceList.cpp index 4485268d1fd0..35ba779f9256 100644 --- a/dom/offline/nsDOMOfflineResourceList.cpp +++ b/dom/offline/nsDOMOfflineResourceList.cpp @@ -62,7 +62,6 @@ NS_IMPL_CYCLE_COLLECTION_INHERITED(nsDOMOfflineResourceList, mPendingEvents) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMOfflineResourceList) - NS_INTERFACE_MAP_ENTRY(nsIDOMOfflineResourceList) NS_INTERFACE_MAP_ENTRY(nsIOfflineCacheUpdateObserver) NS_INTERFACE_MAP_ENTRY(nsIObserver) NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) @@ -81,7 +80,7 @@ nsDOMOfflineResourceList::nsDOMOfflineResourceList(nsIURI *aManifestURI, , mDocumentURI(aDocumentURI) , mLoadingPrincipal(aLoadingPrincipal) , mExposeCacheUpdateStatus(true) - , mStatus(nsIDOMOfflineResourceList::IDLE) + , mStatus(OfflineResourceList_Binding::IDLE) , mCachedKeys(nullptr) , mCachedKeysCount(0) { @@ -173,10 +172,6 @@ nsDOMOfflineResourceList::Disconnect() } } -// -// nsDOMOfflineResourceList::nsIDOMOfflineResourceList -// - already_AddRefed nsDOMOfflineResourceList::GetMozItems(ErrorResult& aRv) { @@ -216,177 +211,250 @@ nsDOMOfflineResourceList::GetMozItems(ErrorResult& aRv) return items.forget(); } -NS_IMETHODIMP -nsDOMOfflineResourceList::GetMozItems(nsISupports** aItems) +bool +nsDOMOfflineResourceList::MozHasItem(const nsAString& aURI, ErrorResult& aRv) { - ErrorResult rv; - RefPtr items = GetMozItems(rv); - items.forget(aItems); - return rv.StealNSResult(); -} - -NS_IMETHODIMP -nsDOMOfflineResourceList::MozHasItem(const nsAString& aURI, bool* aExists) -{ - if (IS_CHILD_PROCESS()) - return NS_ERROR_NOT_IMPLEMENTED; + if (IS_CHILD_PROCESS()) { + aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); + return false; + } nsresult rv = Init(); - NS_ENSURE_SUCCESS(rv, rv); + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(rv); + return false; + } nsCOMPtr appCache = GetDocumentAppCache(); if (!appCache) { - return NS_ERROR_DOM_INVALID_STATE_ERR; + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return false; } nsAutoCString key; rv = GetCacheKey(aURI, key); - NS_ENSURE_SUCCESS(rv, rv); + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(rv); + return false; + } uint32_t types; rv = appCache->GetTypes(key, &types); if (rv == NS_ERROR_CACHE_KEY_NOT_FOUND) { - *aExists = false; - return NS_OK; + return false; + } + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(rv); + return false; } - NS_ENSURE_SUCCESS(rv, rv); - *aExists = ((types & nsIApplicationCache::ITEM_DYNAMIC) != 0); - return NS_OK; + return types & nsIApplicationCache::ITEM_DYNAMIC; } -NS_IMETHODIMP -nsDOMOfflineResourceList::GetMozLength(uint32_t *aLength) +uint32_t +nsDOMOfflineResourceList::GetMozLength(ErrorResult& aRv) { - if (IS_CHILD_PROCESS()) - return NS_ERROR_NOT_IMPLEMENTED; + if (IS_CHILD_PROCESS()) { + aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); + return 0; + } if (!mManifestURI) { - *aLength = 0; - return NS_OK; + return 0; } nsresult rv = Init(); - NS_ENSURE_SUCCESS(rv, rv); + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(rv); + return 0; + } rv = CacheKeys(); - NS_ENSURE_SUCCESS(rv, rv); + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(rv); + return 0; + } - *aLength = mCachedKeysCount; - return NS_OK; + return mCachedKeysCount; } -NS_IMETHODIMP -nsDOMOfflineResourceList::MozItem(uint32_t aIndex, nsAString& aURI) +void +nsDOMOfflineResourceList::MozItem(uint32_t aIndex, nsAString& aURI, + ErrorResult& aRv) { - if (IS_CHILD_PROCESS()) - return NS_ERROR_NOT_IMPLEMENTED; + bool found; + IndexedGetter(aIndex, found, aURI, aRv); + if (!aRv.Failed() && !found) { + aRv.Throw(NS_ERROR_NOT_AVAILABLE); + } +} + +void +nsDOMOfflineResourceList::IndexedGetter(uint32_t aIndex, bool& aFound, + nsAString& aURI, ErrorResult& aRv) +{ + if (IS_CHILD_PROCESS()) { + aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); + return; + } nsresult rv = Init(); - NS_ENSURE_SUCCESS(rv, rv); - - SetDOMStringToNull(aURI); + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(rv); + return; + } rv = CacheKeys(); - NS_ENSURE_SUCCESS(rv, rv); + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(rv); + return; + } - if (aIndex >= mCachedKeysCount) - return NS_ERROR_NOT_AVAILABLE; + if (aIndex >= mCachedKeysCount) { + aFound = false; + return; + } + aFound = true; CopyUTF8toUTF16(mCachedKeys[aIndex], aURI); - - return NS_OK; } -NS_IMETHODIMP -nsDOMOfflineResourceList::MozAdd(const nsAString& aURI) +void +nsDOMOfflineResourceList::MozAdd(const nsAString& aURI, ErrorResult& aRv) { - if (IS_CHILD_PROCESS()) - return NS_ERROR_NOT_IMPLEMENTED; + if (IS_CHILD_PROCESS()) { + aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); + return; + } nsresult rv = Init(); - NS_ENSURE_SUCCESS(rv, rv); + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(rv); + return; + } if (!nsContentUtils::OfflineAppAllowed(mDocumentURI)) { - return NS_ERROR_DOM_SECURITY_ERR; + aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); + return; } nsCOMPtr appCache = GetDocumentAppCache(); if (!appCache) { - return NS_ERROR_DOM_INVALID_STATE_ERR; + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return; } - if (aURI.Length() > MAX_URI_LENGTH) return NS_ERROR_DOM_BAD_URI; + if (aURI.Length() > MAX_URI_LENGTH) { + aRv.Throw(NS_ERROR_DOM_BAD_URI); + return; + } // this will fail if the URI is not absolute nsCOMPtr requestedURI; rv = NS_NewURI(getter_AddRefs(requestedURI), aURI); - NS_ENSURE_SUCCESS(rv, rv); + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(rv); + return; + } nsAutoCString scheme; rv = requestedURI->GetScheme(scheme); - NS_ENSURE_SUCCESS(rv, rv); + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(rv); + return; + } bool match; rv = mManifestURI->SchemeIs(scheme.get(), &match); - NS_ENSURE_SUCCESS(rv, rv); - - if (!match) { - return NS_ERROR_DOM_SECURITY_ERR; + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(rv); + return; } - uint32_t length; - rv = GetMozLength(&length); - NS_ENSURE_SUCCESS(rv, rv); + if (!match) { + aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); + return; + } + + uint32_t length = GetMozLength(aRv); + if (NS_WARN_IF(aRv.Failed())) { + return; + } uint32_t maxEntries = Preferences::GetUint(kMaxEntriesPref, DEFAULT_MAX_ENTRIES); - if (length > maxEntries) return NS_ERROR_NOT_AVAILABLE; + if (length > maxEntries) { + aRv.Throw(NS_ERROR_NOT_AVAILABLE); + return; + } ClearCachedKeys(); nsCOMPtr update = do_CreateInstance(NS_OFFLINECACHEUPDATE_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(rv); + return; + } nsAutoCString clientID; rv = appCache->GetClientID(clientID); - NS_ENSURE_SUCCESS(rv, rv); + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(rv); + return; + } rv = update->InitPartial(mManifestURI, clientID, mDocumentURI, mLoadingPrincipal); - NS_ENSURE_SUCCESS(rv, rv); + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(rv); + return; + } rv = update->AddDynamicURI(requestedURI); - NS_ENSURE_SUCCESS(rv, rv); + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(rv); + return; + } rv = update->Schedule(); - NS_ENSURE_SUCCESS(rv, rv); - - return NS_OK; + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(rv); + return; + } } -NS_IMETHODIMP -nsDOMOfflineResourceList::MozRemove(const nsAString& aURI) +void +nsDOMOfflineResourceList::MozRemove(const nsAString& aURI, ErrorResult& aRv) { - if (IS_CHILD_PROCESS()) - return NS_ERROR_NOT_IMPLEMENTED; + if (IS_CHILD_PROCESS()) { + aRv.Throw(NS_ERROR_NOT_IMPLEMENTED); + return; + } nsresult rv = Init(); - NS_ENSURE_SUCCESS(rv, rv); + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(rv); + return; + } if (!nsContentUtils::OfflineAppAllowed(mDocumentURI)) { - return NS_ERROR_DOM_SECURITY_ERR; + aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); + return; } nsCOMPtr appCache = GetDocumentAppCache(); if (!appCache) { - return NS_ERROR_DOM_INVALID_STATE_ERR; + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return; } nsAutoCString key; rv = GetCacheKey(aURI, key); - NS_ENSURE_SUCCESS(rv, rv); + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(rv); + return; + } ClearCachedKeys(); @@ -397,13 +465,14 @@ nsDOMOfflineResourceList::MozRemove(const nsAString& aURI) // finished. Need to bring this issue up. rv = appCache->UnmarkEntry(key, nsIApplicationCache::ITEM_DYNAMIC); - NS_ENSURE_SUCCESS(rv, rv); - - return NS_OK; + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(rv); + return; + } } -NS_IMETHODIMP -nsDOMOfflineResourceList::GetStatus(uint16_t *aStatus) +uint16_t +nsDOMOfflineResourceList::GetStatus(ErrorResult& aRv) { nsresult rv = Init(); @@ -412,89 +481,106 @@ nsDOMOfflineResourceList::GetStatus(uint16_t *aStatus) // to an UNCACHED. if (rv == NS_ERROR_DOM_INVALID_STATE_ERR || !nsContentUtils::OfflineAppAllowed(mDocumentURI)) { - *aStatus = nsIDOMOfflineResourceList::UNCACHED; - return NS_OK; + return OfflineResourceList_Binding::UNCACHED; } - NS_ENSURE_SUCCESS(rv, rv); + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(rv); + return 0; + } // If this object is not associated with a cache, return UNCACHED nsCOMPtr appCache = GetDocumentAppCache(); if (!appCache) { - *aStatus = nsIDOMOfflineResourceList::UNCACHED; - return NS_OK; + return OfflineResourceList_Binding::UNCACHED; } // If there is an update in process, use its status. if (mCacheUpdate && mExposeCacheUpdateStatus) { - rv = mCacheUpdate->GetStatus(aStatus); - if (NS_SUCCEEDED(rv) && *aStatus != nsIDOMOfflineResourceList::IDLE) { - return NS_OK; + uint16_t status; + rv = mCacheUpdate->GetStatus(&status); + if (NS_SUCCEEDED(rv) && status != OfflineResourceList_Binding::IDLE) { + return status; } } if (mAvailableApplicationCache) { - *aStatus = nsIDOMOfflineResourceList::UPDATEREADY; - return NS_OK; + return OfflineResourceList_Binding::UPDATEREADY; } - *aStatus = mStatus; - return NS_OK; + return mStatus; } -NS_IMETHODIMP -nsDOMOfflineResourceList::Update() +void +nsDOMOfflineResourceList::Update(ErrorResult& aRv) { nsresult rv = Init(); - NS_ENSURE_SUCCESS(rv, rv); + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(rv); + return; + } if (!nsContentUtils::OfflineAppAllowed(mDocumentURI)) { - return NS_ERROR_DOM_SECURITY_ERR; + aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); + return; } nsCOMPtr updateService = do_GetService(NS_OFFLINECACHEUPDATESERVICE_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(rv); + return; + } nsCOMPtr window = GetOwner(); nsCOMPtr update; rv = updateService->ScheduleUpdate(mManifestURI, mDocumentURI, mLoadingPrincipal, window, getter_AddRefs(update)); - NS_ENSURE_SUCCESS(rv, rv); - - return NS_OK; + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(rv); + return; + } } -NS_IMETHODIMP -nsDOMOfflineResourceList::SwapCache() +void +nsDOMOfflineResourceList::SwapCache(ErrorResult& aRv) { nsresult rv = Init(); - NS_ENSURE_SUCCESS(rv, rv); + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(rv); + return; + } if (!nsContentUtils::OfflineAppAllowed(mDocumentURI)) { - return NS_ERROR_DOM_SECURITY_ERR; + aRv.Throw(NS_ERROR_DOM_SECURITY_ERR); + return; } nsCOMPtr currentAppCache = GetDocumentAppCache(); if (!currentAppCache) { - return NS_ERROR_DOM_INVALID_STATE_ERR; + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return; } // Check the current and potentially newly available cache are not identical. if (mAvailableApplicationCache == currentAppCache) { - return NS_ERROR_DOM_INVALID_STATE_ERR; + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return; } if (mAvailableApplicationCache) { nsCString currClientId, availClientId; currentAppCache->GetClientID(currClientId); mAvailableApplicationCache->GetClientID(availClientId); - if (availClientId == currClientId) - return NS_ERROR_DOM_INVALID_STATE_ERR; - } else if (mStatus != OBSOLETE) { - return NS_ERROR_DOM_INVALID_STATE_ERR; + if (availClientId == currClientId) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return; + } + } else if (mStatus != OfflineResourceList_Binding::OBSOLETE) { + aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); + return; } ClearCachedKeys(); @@ -506,13 +592,14 @@ nsDOMOfflineResourceList::SwapCache() // We will disassociate from the cache in that case. if (appCacheContainer) { rv = appCacheContainer->SetApplicationCache(mAvailableApplicationCache); - NS_ENSURE_SUCCESS(rv, rv); + if (NS_WARN_IF(NS_FAILED(rv))) { + aRv.Throw(rv); + return; + } } mAvailableApplicationCache = nullptr; - mStatus = nsIDOMOfflineResourceList::IDLE; - - return NS_OK; + mStatus = OfflineResourceList_Binding::IDLE; } void @@ -605,7 +692,7 @@ nsDOMOfflineResourceList::UpdateStateChanged(nsIOfflineCacheUpdate *aUpdate, SendEvent(NS_LITERAL_STRING(NOUPDATE_STR)); break; case STATE_OBSOLETE: - mStatus = nsIDOMOfflineResourceList::OBSOLETE; + mStatus = OfflineResourceList_Binding::OBSOLETE; mAvailableApplicationCache = nullptr; SendEvent(NS_LITERAL_STRING(OBSOLETE_STR)); break; @@ -756,7 +843,7 @@ nsDOMOfflineResourceList::UpdateCompleted(nsIOfflineCacheUpdate *aUpdate) mCacheUpdate = nullptr; if (NS_SUCCEEDED(rv) && succeeded && !partial) { - mStatus = nsIDOMOfflineResourceList::IDLE; + mStatus = OfflineResourceList_Binding::IDLE; if (isUpgrade) { SendEvent(NS_LITERAL_STRING(UPDATEREADY_STR)); } else { diff --git a/dom/offline/nsDOMOfflineResourceList.h b/dom/offline/nsDOMOfflineResourceList.h index f2a78b4e7a90..9a354acf9114 100644 --- a/dom/offline/nsDOMOfflineResourceList.h +++ b/dom/offline/nsDOMOfflineResourceList.h @@ -8,7 +8,6 @@ #define nsDOMOfflineResourceList_h___ #include "nscore.h" -#include "nsIDOMOfflineResourceList.h" #include "nsIApplicationCache.h" #include "nsIApplicationCacheContainer.h" #include "nsIApplicationCacheService.h" @@ -35,7 +34,6 @@ class Event; } // namespace mozilla class nsDOMOfflineResourceList final : public mozilla::DOMEventTargetHelper, - public nsIDOMOfflineResourceList, public nsIObserver, public nsIOfflineCacheUpdateObserver, public nsSupportsWeakReference @@ -44,7 +42,6 @@ class nsDOMOfflineResourceList final : public mozilla::DOMEventTargetHelper, public: NS_DECL_ISUPPORTS_INHERITED - NS_DECL_NSIDOMOFFLINERESOURCELIST NS_DECL_NSIOBSERVER NS_DECL_NSIOFFLINECACHEUPDATEOBSERVER @@ -68,20 +65,11 @@ public: virtual JSObject* WrapObject(JSContext* aCx, JS::Handle aGivenProto) override; - uint16_t GetStatus(ErrorResult& aRv) - { - uint16_t status = 0; - aRv = GetStatus(&status); - return status; - } - void Update(ErrorResult& aRv) - { - aRv = Update(); - } - void SwapCache(ErrorResult& aRv) - { - aRv = SwapCache(); - } + uint16_t GetStatus(ErrorResult& aRv); + + void Update(ErrorResult& aRv); + + void SwapCache(ErrorResult& aRv); IMPL_EVENT_HANDLER(checking) IMPL_EVENT_HANDLER(error) @@ -93,42 +81,19 @@ public: IMPL_EVENT_HANDLER(obsolete) already_AddRefed GetMozItems(ErrorResult& aRv); - bool MozHasItem(const nsAString& aURI, ErrorResult& aRv) - { - bool hasItem = false; - aRv = MozHasItem(aURI, &hasItem); - return hasItem; - } - uint32_t GetMozLength(ErrorResult& aRv) - { - uint32_t length = 0; - aRv = GetMozLength(&length); - return length; - } - void MozItem(uint32_t aIndex, nsAString& aURI, ErrorResult& aRv) - { - aRv = MozItem(aIndex, aURI); - } + bool MozHasItem(const nsAString& aURI, ErrorResult& aRv); + uint32_t GetMozLength(ErrorResult& aRv); + void MozItem(uint32_t aIndex, nsAString& aURI, ErrorResult& aRv); void IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aURI, - ErrorResult& aRv) - { - MozItem(aIndex, aURI, aRv); - aFound = !aURI.IsVoid(); - } + ErrorResult& aRv); uint32_t Length() { mozilla::IgnoredErrorResult rv; uint32_t length = GetMozLength(rv); return rv.Failed() ? 0 : length; } - void MozAdd(const nsAString& aURI, ErrorResult& aRv) - { - aRv = MozAdd(aURI); - } - void MozRemove(const nsAString& aURI, ErrorResult& aRv) - { - aRv = MozRemove(aURI); - } + void MozAdd(const nsAString& aURI, ErrorResult& aRv); + void MozRemove(const nsAString& aURI, ErrorResult& aRv); protected: virtual ~nsDOMOfflineResourceList(); diff --git a/dom/storage/LocalStorage.cpp b/dom/storage/LocalStorage.cpp index 762f62c37ae6..609c3bec8b09 100644 --- a/dom/storage/LocalStorage.cpp +++ b/dom/storage/LocalStorage.cpp @@ -134,7 +134,7 @@ LocalStorage::SetItem(const nsAString& aKey, const nsAString& aData, } if (!aRv.ErrorCodeIs(NS_SUCCESS_DOM_NO_OPERATION)) { - BroadcastChangeNotification(aKey, old, aData); + OnChange(aKey, old, aData); } } @@ -154,7 +154,7 @@ LocalStorage::RemoveItem(const nsAString& aKey, nsIPrincipal& aSubjectPrincipal, } if (!aRv.ErrorCodeIs(NS_SUCCESS_DOM_NO_OPERATION)) { - BroadcastChangeNotification(aKey, old, VoidString()); + OnChange(aKey, old, VoidString()); } } @@ -172,47 +172,24 @@ LocalStorage::Clear(nsIPrincipal& aSubjectPrincipal, ErrorResult& aRv) } if (!aRv.ErrorCodeIs(NS_SUCCESS_DOM_NO_OPERATION)) { - BroadcastChangeNotification(VoidString(), VoidString(), VoidString()); + OnChange(VoidString(), VoidString(), VoidString()); } } void -LocalStorage::BroadcastChangeNotification(const nsAString& aKey, - const nsAString& aOldValue, - const nsAString& aNewValue) +LocalStorage::OnChange(const nsAString& aKey, + const nsAString& aOldValue, + const nsAString& aNewValue) { - if (Principal()) { - // We want to send a message to the parent in order to broadcast the - // StorageEvent correctly to any child process. - - PBackgroundChild* actor = BackgroundChild::GetForCurrentThread(); - MOZ_ASSERT(actor); - - PrincipalInfo principalInfo; - nsresult rv = PrincipalToPrincipalInfo(Principal(), &principalInfo); - if (!NS_WARN_IF(NS_FAILED(rv))) { - Unused << NS_WARN_IF(!actor->SendBroadcastLocalStorageChange( - mDocumentURI, nsString(aKey), nsString(aOldValue), nsString(aNewValue), - principalInfo, mIsPrivate)); - } - } - - DispatchStorageEvent(mDocumentURI, aKey, aOldValue, aNewValue, - Principal(), mIsPrivate, this, false); -} - -/* static */ void -LocalStorage::DispatchStorageEvent(const nsAString& aDocumentURI, - const nsAString& aKey, - const nsAString& aOldValue, - const nsAString& aNewValue, - nsIPrincipal* aPrincipal, - bool aIsPrivate, - Storage* aStorage, - bool aImmediateDispatch) -{ - NotifyChange(aStorage, aPrincipal, aKey, aOldValue, aNewValue, - u"localStorage", aDocumentURI, aIsPrivate, aImmediateDispatch); + NotifyChange(/* aStorage */ this, + Principal(), + aKey, + aOldValue, + aNewValue, + /* aStorageType */ u"localStorage", + mDocumentURI, + mIsPrivate, + /* aImmediateDispatch */ false); } void diff --git a/dom/storage/LocalStorage.h b/dom/storage/LocalStorage.h index 6dd5388ae40b..36cb248c5f20 100644 --- a/dom/storage/LocalStorage.h +++ b/dom/storage/LocalStorage.h @@ -36,6 +36,12 @@ public: return mCache; } + const nsString& + DocumentURI() const + { + return mDocumentURI; + } + bool PrincipalEquals(nsIPrincipal* aPrincipal); LocalStorage(nsPIDOMWindowInner* aWindow, @@ -77,24 +83,6 @@ public: bool IsPrivate() const { return mIsPrivate; } - // aStorage can be null if this method is called by ContentChild. - // - // aImmediateDispatch is for use by (main-thread) IPC code so that PContent - // ordering can be maintained. Without this, the event would be enqueued and - // run in a future turn of the event loop, potentially allowing other PContent - // Recv* methods to trigger script that wants to assume our localstorage - // changes have already been applied. This is the case for message manager - // messages which are used by ContentTask testing logic and webextensions. - static void - DispatchStorageEvent(const nsAString& aDocumentURI, - const nsAString& aKey, - const nsAString& aOldValue, - const nsAString& aNewValue, - nsIPrincipal* aPrincipal, - bool aIsPrivate, - Storage* aStorage, - bool aImmediateDispatch); - void ApplyEvent(StorageEvent* aStorageEvent); @@ -115,9 +103,9 @@ private: // Whether this storage is running in private-browsing window. bool mIsPrivate : 1; - void BroadcastChangeNotification(const nsAString& aKey, - const nsAString& aOldValue, - const nsAString& aNewValue); + void OnChange(const nsAString& aKey, + const nsAString& aOldValue, + const nsAString& aNewValue); }; } // namespace dom diff --git a/dom/storage/LocalStorageCache.cpp b/dom/storage/LocalStorageCache.cpp index 807acd56a07e..9e194db36c29 100644 --- a/dom/storage/LocalStorageCache.cpp +++ b/dom/storage/LocalStorageCache.cpp @@ -75,7 +75,8 @@ NS_IMETHODIMP_(void) LocalStorageCacheBridge::Release(void) // LocalStorageCache LocalStorageCache::LocalStorageCache(const nsACString* aOriginNoSuffix) - : mOriginNoSuffix(*aOriginNoSuffix) + : mActor(nullptr) + , mOriginNoSuffix(*aOriginNoSuffix) , mMonitor("LocalStorageCache") , mLoaded(false) , mLoadResult(NS_OK) @@ -89,6 +90,11 @@ LocalStorageCache::LocalStorageCache(const nsACString* aOriginNoSuffix) LocalStorageCache::~LocalStorageCache() { + if (mActor) { + mActor->SendDeleteMeInternal(); + MOZ_ASSERT(!mActor, "SendDeleteMeInternal should have cleared!"); + } + if (mManager) { mManager->DropCache(this); } @@ -96,6 +102,16 @@ LocalStorageCache::~LocalStorageCache() MOZ_COUNT_DTOR(LocalStorageCache); } +void +LocalStorageCache::SetActor(LocalStorageCacheChild* aActor) +{ + AssertIsOnOwningThread(); + MOZ_ASSERT(aActor); + MOZ_ASSERT(!mActor); + + mActor = aActor; +} + NS_IMETHODIMP_(void) LocalStorageCache::Release(void) { @@ -152,6 +168,28 @@ LocalStorageCache::Init(LocalStorageManager* aManager, mUsage = aManager->GetOriginUsage(mQuotaOriginScope); } +void +LocalStorageCache::NotifyObservers(const LocalStorage* aStorage, + const nsString& aKey, + const nsString& aOldValue, + const nsString& aNewValue) +{ + AssertIsOnOwningThread(); + MOZ_ASSERT(aStorage); + + if (!mActor) { + return; + } + + // We want to send a message to the parent in order to broadcast the + // StorageEvent correctly to any child process. + + Unused << mActor->SendNotify(aStorage->DocumentURI(), + aKey, + aOldValue, + aNewValue); +} + inline bool LocalStorageCache::Persist(const LocalStorage* aStorage) const { @@ -401,7 +439,13 @@ LocalStorageCache::SetItem(const LocalStorage* aStorage, const nsAString& aKey, data.mKeys.Put(aKey, aValue); - if (aSource == ContentMutation && Persist(aStorage)) { + if (aSource != ContentMutation) { + return NS_OK; + } + + NotifyObservers(aStorage, nsString(aKey), aOld, aValue); + + if (Persist(aStorage)) { StorageDBChild* storageChild = StorageDBChild::Get(); if (!storageChild) { NS_ERROR("Writing to localStorage after the database has been shut down" @@ -443,7 +487,13 @@ LocalStorageCache::RemoveItem(const LocalStorage* aStorage, Unused << ProcessUsageDelta(aStorage, delta, aSource); data.mKeys.Remove(aKey); - if (aSource == ContentMutation && Persist(aStorage)) { + if (aSource != ContentMutation) { + return NS_OK; + } + + NotifyObservers(aStorage, nsString(aKey), aOld, VoidString()); + + if (Persist(aStorage)) { StorageDBChild* storageChild = StorageDBChild::Get(); if (!storageChild) { NS_ERROR("Writing to localStorage after the database has been shut down" @@ -485,7 +535,15 @@ LocalStorageCache::Clear(const LocalStorage* aStorage, data.mKeys.Clear(); } - if (aSource == ContentMutation && Persist(aStorage) && (refresh || hadData)) { + if (aSource != ContentMutation) { + return hadData ? NS_OK : NS_SUCCESS_DOM_NO_OPERATION; + } + + if (hadData) { + NotifyObservers(aStorage, VoidString(), VoidString(), VoidString()); + } + + if (Persist(aStorage) && (refresh || hadData)) { StorageDBChild* storageChild = StorageDBChild::Get(); if (!storageChild) { NS_ERROR("Writing to localStorage after the database has been shut down" diff --git a/dom/storage/LocalStorageCache.h b/dom/storage/LocalStorageCache.h index e974c8a30f71..fed7becf25af 100644 --- a/dom/storage/LocalStorageCache.h +++ b/dom/storage/LocalStorageCache.h @@ -21,6 +21,7 @@ namespace mozilla { namespace dom { class LocalStorage; +class LocalStorageCacheChild; class LocalStorageManager; class StorageUsage; class StorageDBBridge; @@ -76,6 +77,23 @@ protected: class LocalStorageCache : public LocalStorageCacheBridge { public: + void + AssertIsOnOwningThread() const + { + NS_ASSERT_OWNINGTHREAD(LocalStorage); + } + + void + SetActor(LocalStorageCacheChild* aActor); + + void + ClearActor() + { + AssertIsOnOwningThread(); + + mActor = nullptr; + } + NS_IMETHOD_(void) Release(void) override; enum MutationSource { @@ -181,6 +199,13 @@ private: // Helper to get one of the 3 data sets (regular, private, session) Data& DataSet(const LocalStorage* aStorage); + // Used for firing storage events and synchronization of caches in other + // content processes. + void NotifyObservers(const LocalStorage* aStorage, + const nsString& aKey, + const nsString& aOldValue, + const nsString& aNewValue); + // Whether the storage change is about to persist bool Persist(const LocalStorage* aStorage) const; @@ -210,6 +235,14 @@ private: // Obtained from the manager during initialization (Init method). RefPtr mUsage; + // The LocalStorageCacheChild is created at the same time of this class. + // In normal operation, the actor will be synchronously cleared in our + // destructor when we tell it to delete itself. In a shutdown-related edge + // case in the parent process for JSM's, it is possible for the actor to be + // destroyed while this class remains alive, in which case it will be nulled + // out. + LocalStorageCacheChild* mActor; + // The origin this cache belongs to in the "DB format", i.e. reversed nsCString mOriginNoSuffix; diff --git a/dom/storage/LocalStorageManager.cpp b/dom/storage/LocalStorageManager.cpp index dccddd058a3e..15cf8aa36963 100644 --- a/dom/storage/LocalStorageManager.cpp +++ b/dom/storage/LocalStorageManager.cpp @@ -246,9 +246,38 @@ LocalStorageManager::GetStorageInternal(CreateMode aCreateMode, } } + PBackgroundChild* backgroundActor = + BackgroundChild::GetOrCreateForCurrentThread(); + if (NS_WARN_IF(!backgroundActor)) { + return NS_ERROR_FAILURE; + } + + PrincipalInfo principalInfo; + rv = mozilla::ipc::PrincipalToPrincipalInfo(aPrincipal, &principalInfo); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + uint32_t privateBrowsingId; + rv = aPrincipal->GetPrivateBrowsingId(&privateBrowsingId); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + // There is always a single instance of a cache per scope // in a single instance of a DOM storage manager. cache = PutCache(originAttrSuffix, originKey, aPrincipal); + + LocalStorageCacheChild* actor = new LocalStorageCacheChild(cache); + + MOZ_ALWAYS_TRUE( + backgroundActor->SendPBackgroundLocalStorageCacheConstructor( + actor, + principalInfo, + originKey, + privateBrowsingId)); + + cache->SetActor(actor); } if (aRetval) { diff --git a/dom/storage/PBackgroundLocalStorageCache.ipdl b/dom/storage/PBackgroundLocalStorageCache.ipdl new file mode 100644 index 000000000000..45391448ada4 --- /dev/null +++ b/dom/storage/PBackgroundLocalStorageCache.ipdl @@ -0,0 +1,41 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +include protocol PBackground; + +include PBackgroundSharedTypes; + +namespace mozilla { +namespace dom { + +async protocol PBackgroundLocalStorageCache +{ + manager PBackground; + +parent: + async DeleteMe(); + + async Notify(nsString documentURI, + nsString key, + nsString oldValue, + nsString newValue); + +child: + // The principalInfo and privateBrowsingId could instead be retained by the + // LocalStorageCacheChild/LocalStorageCache instead of being re-transmitted. + // However, these changes are a temporary optimization intended for uplift, + // and this constant factor overhead is very small compared to the upside of + // filtering. + async Observe(PrincipalInfo principalInfo, + uint32_t privateBrowsingId, + nsString documentURI, + nsString key, + nsString oldValue, + nsString newValue); + + async __delete__(); +}; + +} // namespace dom +} // namespace mozilla diff --git a/dom/storage/Storage.h b/dom/storage/Storage.h index c8a0ee07bf4f..4ee8e2982c03 100644 --- a/dom/storage/Storage.h +++ b/dom/storage/Storage.h @@ -111,6 +111,15 @@ public: bool IsSessionOnly() const { return mIsSessionOnly; } + // aStorage can be null if this method is called by LocalStorageCacheChild. + // + // aImmediateDispatch is for use by child IPC code (LocalStorageCacheChild) + // so that PBackground ordering can be maintained. Without this, the event + // would be/ enqueued and run in a future turn of the event loop, potentially + // allowing other PBackground Recv* methods to trigger script that wants to + // assume our localstorage changes have already been applied. This is the + // case for message manager messages which are used by ContentTask testing + // logic and webextensions. static void NotifyChange(Storage* aStorage, nsIPrincipal* aPrincipal, const nsAString& aKey, const nsAString& aOldValue, diff --git a/dom/storage/StorageIPC.cpp b/dom/storage/StorageIPC.cpp index ed0ea3f0400c..02f535967d37 100644 --- a/dom/storage/StorageIPC.cpp +++ b/dom/storage/StorageIPC.cpp @@ -23,6 +23,11 @@ namespace dom { namespace { +typedef nsClassHashtable> + LocalStorageCacheParentHashtable; + +StaticAutoPtr gLocalStorageCacheParents; + StorageDBChild* sStorageChild = nullptr; // False until we shut the storage child down. @@ -30,6 +35,77 @@ bool sStorageChildDown = false; } +LocalStorageCacheChild::LocalStorageCacheChild(LocalStorageCache* aCache) + : mCache(aCache) +{ + AssertIsOnOwningThread(); + MOZ_ASSERT(aCache); + aCache->AssertIsOnOwningThread(); + + MOZ_COUNT_CTOR(LocalStorageCacheChild); +} + +LocalStorageCacheChild::~LocalStorageCacheChild() +{ + AssertIsOnOwningThread(); + + MOZ_COUNT_DTOR(LocalStorageCacheChild); +} + +void +LocalStorageCacheChild::SendDeleteMeInternal() +{ + AssertIsOnOwningThread(); + + if (mCache) { + mCache->ClearActor(); + mCache = nullptr; + + MOZ_ALWAYS_TRUE(PBackgroundLocalStorageCacheChild::SendDeleteMe()); + } +} + +void +LocalStorageCacheChild::ActorDestroy(ActorDestroyReason aWhy) +{ + AssertIsOnOwningThread(); + + if (mCache) { + mCache->ClearActor(); + mCache = nullptr; + } +} + +mozilla::ipc::IPCResult +LocalStorageCacheChild::RecvObserve(const PrincipalInfo& aPrincipalInfo, + const uint32_t& aPrivateBrowsingId, + const nsString& aDocumentURI, + const nsString& aKey, + const nsString& aOldValue, + const nsString& aNewValue) +{ + AssertIsOnOwningThread(); + + nsresult rv; + nsCOMPtr principal = + PrincipalInfoToPrincipal(aPrincipalInfo, &rv); + if (NS_WARN_IF(NS_FAILED(rv))) { + return IPC_FAIL_NO_REASON(this); + } + + Storage::NotifyChange(/* aStorage */ nullptr, + principal, + aKey, + aOldValue, + aNewValue, + /* aStorageType */ u"localStorage", + aDocumentURI, + /* aIsPrivate */ !!aPrivateBrowsingId, + /* aImmediateDispatch */ true); + + return IPC_OK(); +} + // ---------------------------------------------------------------------------- // Child // ---------------------------------------------------------------------------- @@ -396,6 +472,88 @@ ShutdownObserver::Observe(nsISupports* aSubject, return NS_OK; } +LocalStorageCacheParent::LocalStorageCacheParent( + const PrincipalInfo& aPrincipalInfo, + const nsACString& aOriginKey, + uint32_t aPrivateBrowsingId) + : mPrincipalInfo(aPrincipalInfo) + , mOriginKey(aOriginKey) + , mPrivateBrowsingId(aPrivateBrowsingId) + , mActorDestroyed(false) +{ + AssertIsOnBackgroundThread(); +} + +LocalStorageCacheParent::~LocalStorageCacheParent() +{ + MOZ_ASSERT(mActorDestroyed); +} + +void +LocalStorageCacheParent::ActorDestroy(ActorDestroyReason aWhy) +{ + AssertIsOnBackgroundThread(); + MOZ_ASSERT(!mActorDestroyed); + + mActorDestroyed = true; + + MOZ_ASSERT(gLocalStorageCacheParents); + + nsTArray* array; + gLocalStorageCacheParents->Get(mOriginKey, &array); + MOZ_ASSERT(array); + + array->RemoveElement(this); + + if (array->IsEmpty()) { + gLocalStorageCacheParents->Remove(mOriginKey); + } + + if (!gLocalStorageCacheParents->Count()) { + gLocalStorageCacheParents = nullptr; + } +} + +mozilla::ipc::IPCResult +LocalStorageCacheParent::RecvDeleteMe() +{ + AssertIsOnBackgroundThread(); + MOZ_ASSERT(!mActorDestroyed); + + IProtocol* mgr = Manager(); + if (!PBackgroundLocalStorageCacheParent::Send__delete__(this)) { + return IPC_FAIL_NO_REASON(mgr); + } + return IPC_OK(); +} + +mozilla::ipc::IPCResult +LocalStorageCacheParent::RecvNotify(const nsString& aDocumentURI, + const nsString& aKey, + const nsString& aOldValue, + const nsString& aNewValue) +{ + AssertIsOnBackgroundThread(); + MOZ_ASSERT(gLocalStorageCacheParents); + + nsTArray* array; + gLocalStorageCacheParents->Get(mOriginKey, &array); + MOZ_ASSERT(array); + + for (LocalStorageCacheParent* localStorageCacheParent : *array) { + if (localStorageCacheParent != this) { + Unused << localStorageCacheParent->SendObserve(mPrincipalInfo, + mPrivateBrowsingId, + aDocumentURI, + aKey, + aOldValue, + aNewValue); + } + } + + return IPC_OK(); +} + // ---------------------------------------------------------------------------- // Parent // ---------------------------------------------------------------------------- @@ -1228,6 +1386,66 @@ ObserverSink::Observe(const char* aTopic, * Exported functions ******************************************************************************/ +PBackgroundLocalStorageCacheParent* +AllocPBackgroundLocalStorageCacheParent( + const mozilla::ipc::PrincipalInfo& aPrincipalInfo, + const nsCString& aOriginKey, + const uint32_t& aPrivateBrowsingId) +{ + AssertIsOnBackgroundThread(); + + RefPtr actor = + new LocalStorageCacheParent(aPrincipalInfo, aOriginKey, aPrivateBrowsingId); + + // Transfer ownership to IPDL. + return actor.forget().take(); +} + +mozilla::ipc::IPCResult +RecvPBackgroundLocalStorageCacheConstructor( + mozilla::ipc::PBackgroundParent* aBackgroundActor, + PBackgroundLocalStorageCacheParent* aActor, + const mozilla::ipc::PrincipalInfo& aPrincipalInfo, + const nsCString& aOriginKey, + const uint32_t& aPrivateBrowsingId) +{ + AssertIsOnBackgroundThread(); + MOZ_ASSERT(aActor); + + auto* actor = static_cast(aActor); + + if (!gLocalStorageCacheParents) { + gLocalStorageCacheParents = new LocalStorageCacheParentHashtable(); + } + + nsTArray* array; + if (!gLocalStorageCacheParents->Get(aOriginKey, &array)) { + array = new nsTArray(); + gLocalStorageCacheParents->Put(aOriginKey, array); + } + array->AppendElement(actor); + + // We are currently trusting the content process not to lie to us. It is + // future work to consult the ClientManager to determine whether this is a + // legitimate origin for the content process. + + return IPC_OK(); +} + +bool +DeallocPBackgroundLocalStorageCacheParent( + PBackgroundLocalStorageCacheParent* aActor) +{ + AssertIsOnBackgroundThread(); + MOZ_ASSERT(aActor); + + // Transfer ownership back from IPDL. + RefPtr actor = + dont_AddRef(static_cast(aActor)); + + return true; +} + PBackgroundStorageParent* AllocPBackgroundStorageParent(const nsString& aProfilePath) { diff --git a/dom/storage/StorageIPC.h b/dom/storage/StorageIPC.h index 0a488d6616ae..52f211889c72 100644 --- a/dom/storage/StorageIPC.h +++ b/dom/storage/StorageIPC.h @@ -7,6 +7,8 @@ #ifndef mozilla_dom_StorageIPC_h #define mozilla_dom_StorageIPC_h +#include "mozilla/dom/PBackgroundLocalStorageCacheChild.h" +#include "mozilla/dom/PBackgroundLocalStorageCacheParent.h" #include "mozilla/dom/PBackgroundStorageChild.h" #include "mozilla/dom/PBackgroundStorageParent.h" #include "StorageDBThread.h" @@ -19,11 +21,65 @@ namespace mozilla { class OriginAttributesPattern; +namespace ipc { + +class BackgroundChildImpl; +class PrincipalInfo; + +} // namespace ipc + namespace dom { class LocalStorageManager; class PBackgroundStorageParent; +class LocalStorageCacheChild final + : public PBackgroundLocalStorageCacheChild +{ + friend class mozilla::ipc::BackgroundChildImpl; + friend class LocalStorageCache; + friend class LocalStorageManager; + + // LocalStorageCache effectively owns this instance, although IPC handles its + // allocation/deallocation. When the LocalStorageCache destructor runs, it + // will invoke SendDeleteMeInternal() which will trigger both instances to + // drop their mutual references and cause IPC to destroy the actor after the + // DeleteMe round-trip. + LocalStorageCache* MOZ_NON_OWNING_REF mCache; + + NS_DECL_OWNINGTHREAD + +public: + void + AssertIsOnOwningThread() const + { + NS_ASSERT_OWNINGTHREAD(LocalStorageCacheChild); + } + +private: + // Only created by LocalStorageManager. + explicit LocalStorageCacheChild(LocalStorageCache* aCache); + + // Only destroyed by mozilla::ipc::BackgroundChildImpl. + ~LocalStorageCacheChild(); + + // Only called by LocalStorageCache. + void + SendDeleteMeInternal(); + + // IPDL methods are only called by IPDL. + void + ActorDestroy(ActorDestroyReason aWhy) override; + + mozilla::ipc::IPCResult + RecvObserve(const PrincipalInfo& aPrincipalInfo, + const uint32_t& aPrivateBrowsingId, + const nsString& aDocumentURI, + const nsString& aKey, + const nsString& aOldValue, + const nsString& aNewValue) override; +}; + // Child side of the IPC protocol, exposes as DB interface but // is responsible to send all requests to the parent process // and expects asynchronous answers. Those are then transparently @@ -126,6 +182,39 @@ private: bool mIPCOpen; }; +class LocalStorageCacheParent final + : public PBackgroundLocalStorageCacheParent +{ + const PrincipalInfo mPrincipalInfo; + const nsCString mOriginKey; + uint32_t mPrivateBrowsingId; + bool mActorDestroyed; + +public: + // Created in AllocPBackgroundLocalStorageCacheParent. + LocalStorageCacheParent(const PrincipalInfo& aPrincipalInfo, + const nsACString& aOriginKey, + uint32_t aPrivateBrowsingId); + + NS_INLINE_DECL_REFCOUNTING(mozilla::dom::LocalStorageCacheParent) + +private: + // Reference counted. + ~LocalStorageCacheParent(); + + // IPDL methods are only called by IPDL. + void + ActorDestroy(ActorDestroyReason aWhy) override; + + mozilla::ipc::IPCResult + RecvDeleteMe() override; + + mozilla::ipc::IPCResult + RecvNotify(const nsString& aDocumentURI, + const nsString& aKey, + const nsString& aOldValue, + const nsString& aNewValue) override; +}; // Receives async requests from child processes and is responsible // to send back responses from the DB thread. Exposes as a fake @@ -283,6 +372,24 @@ private: bool mIPCOpen; }; +PBackgroundLocalStorageCacheParent* +AllocPBackgroundLocalStorageCacheParent( + const mozilla::ipc::PrincipalInfo& aPrincipalInfo, + const nsCString& aOriginKey, + const uint32_t& aPrivateBrowsingId); + +mozilla::ipc::IPCResult +RecvPBackgroundLocalStorageCacheConstructor( + mozilla::ipc::PBackgroundParent* aBackgroundActor, + PBackgroundLocalStorageCacheParent* aActor, + const mozilla::ipc::PrincipalInfo& aPrincipalInfo, + const nsCString& aOriginKey, + const uint32_t& aPrivateBrowsingId); + +bool +DeallocPBackgroundLocalStorageCacheParent( + PBackgroundLocalStorageCacheParent* aActor); + PBackgroundStorageParent* AllocPBackgroundStorageParent(const nsString& aProfilePath); diff --git a/dom/storage/moz.build b/dom/storage/moz.build index 8f0e11b57e9a..4003e44ff18c 100644 --- a/dom/storage/moz.build +++ b/dom/storage/moz.build @@ -36,6 +36,7 @@ UNIFIED_SOURCES += [ ] IPDL_SOURCES += [ + 'PBackgroundLocalStorageCache.ipdl', 'PBackgroundStorage.ipdl', ] diff --git a/dom/tests/mochitest/ajax/offline/foreign2.html b/dom/tests/mochitest/ajax/offline/foreign2.html index 62cbb1e5be04..3d39337aafb4 100644 --- a/dom/tests/mochitest/ajax/offline/foreign2.html +++ b/dom/tests/mochitest/ajax/offline/foreign2.html @@ -46,7 +46,7 @@ function onLoaded() try { - window.opener.OfflineTest.ok(applicationCache.status == SpecialPowers.Ci.nsIDOMOfflineResourceList.UNCACHED, + window.opener.OfflineTest.ok(applicationCache.status == OfflineResourceList.UNCACHED, "there is no associated application cache"); } catch (ex) diff --git a/dom/tests/mochitest/ajax/offline/test_updatingManifest.html b/dom/tests/mochitest/ajax/offline/test_updatingManifest.html index 124d40a85842..b4770c080343 100644 --- a/dom/tests/mochitest/ajax/offline/test_updatingManifest.html +++ b/dom/tests/mochitest/ajax/offline/test_updatingManifest.html @@ -156,7 +156,7 @@ function implicitCached() "https://example.com/tests/dom/tests/mochitest/ajax/offline/fallback.html", false); // Cache object status - OfflineTest.is(applicationCache.status, SpecialPowers.Ci.nsIDOMOfflineResourceList.IDLE, + OfflineTest.is(applicationCache.status, OfflineResourceList.IDLE, "we have associated application cache (1)"); OfflineTest.is(gGotFrameVersion, 1, "IFrame version 1"); @@ -210,7 +210,7 @@ function manifestUpdated() "https://example.com/tests/dom/tests/mochitest/ajax/offline/fallback2.html", false); // Cache object status - OfflineTest.is(applicationCache.status, SpecialPowers.Ci.nsIDOMOfflineResourceList.UPDATEREADY, + OfflineTest.is(applicationCache.status, OfflineResourceList.UPDATEREADY, "we have associated application cache and update is pending (2)"); var entries = [ @@ -259,7 +259,7 @@ function manifestUpdated() "https://example.com/tests/dom/tests/mochitest/ajax/offline/fallback2.html", false); // Cache object status - OfflineTest.is(applicationCache.status, SpecialPowers.Ci.nsIDOMOfflineResourceList.UPDATEREADY, + OfflineTest.is(applicationCache.status, OfflineResourceList.UPDATEREADY, "we have associated application cache and update is pending (3)"); OfflineTest.is(gGotFrameVersion, 1, "IFrame version 1 because cache was not swapped"); @@ -303,10 +303,10 @@ function manifestNoUpdate() OfflineTest.ok(gStep == 3, "Got manifestNoUpdate in step 3, gStep=" + gStep); ++gStep; - OfflineTest.is(applicationCache.status, SpecialPowers.Ci.nsIDOMOfflineResourceList.UPDATEREADY, + OfflineTest.is(applicationCache.status, OfflineResourceList.UPDATEREADY, "we have associated application cache and update is pending (4)"); applicationCache.swapCache(); - OfflineTest.is(applicationCache.status, SpecialPowers.Ci.nsIDOMOfflineResourceList.IDLE, + OfflineTest.is(applicationCache.status, OfflineResourceList.IDLE, "we have associated application cache (4)"); gGotFrameVersion = 0; diff --git a/dom/webidl/Element.webidl b/dom/webidl/Element.webidl index 5201376956de..6650925ba4bd 100644 --- a/dom/webidl/Element.webidl +++ b/dom/webidl/Element.webidl @@ -261,11 +261,15 @@ partial interface Element { [BinaryName="shadowRootByMode", Func="nsDocument::IsShadowDOMEnabled"] readonly attribute ShadowRoot? shadowRoot; - [ChromeOnly, Func="nsDocument::IsShadowDOMEnabled", BinaryName="shadowRoot"] + [Func="nsDocument::IsShadowDOMEnabledAndCallerIsChromeOrAddon", BinaryName="shadowRoot"] readonly attribute ShadowRoot? openOrClosedShadowRoot; [BinaryName="assignedSlotByMode", Func="nsDocument::IsShadowDOMEnabled"] readonly attribute HTMLSlotElement? assignedSlot; + + [ChromeOnly, BinaryName="assignedSlot", Func="nsDocument::IsShadowDOMEnabled"] + readonly attribute HTMLSlotElement? openOrClosedAssignedSlot; + [CEReactions, Unscopable, SetterThrows, Func="nsDocument::IsShadowDOMEnabled"] attribute DOMString slot; }; diff --git a/dom/webidl/Text.webidl b/dom/webidl/Text.webidl index 61041149b096..3b79d6d3725b 100644 --- a/dom/webidl/Text.webidl +++ b/dom/webidl/Text.webidl @@ -21,6 +21,9 @@ interface Text : CharacterData { partial interface Text { [BinaryName="assignedSlotByMode", Func="nsTextNode::IsShadowDOMEnabled"] readonly attribute HTMLSlotElement? assignedSlot; + + [ChromeOnly, BinaryName="assignedSlot", Func="nsTextNode::IsShadowDOMEnabled"] + readonly attribute HTMLSlotElement? openOrClosedAssignedSlot; }; Text implements GeometryUtils; diff --git a/dom/webidl/Window.webidl b/dom/webidl/Window.webidl index 84fb07817c3b..378e70d33665 100644 --- a/dom/webidl/Window.webidl +++ b/dom/webidl/Window.webidl @@ -18,11 +18,12 @@ * https://drafts.css-houdini.org/css-paint-api-1/#dom-window-paintworklet */ -interface ApplicationCache; interface IID; interface nsIBrowserDOMWindow; interface XULControllers; +typedef OfflineResourceList ApplicationCache; + // http://www.whatwg.org/specs/web-apps/current-work/ [PrimaryGlobal, LegacyUnenumerableNamedProperties, NeedResolve] /*sealed*/ interface Window : EventTarget { diff --git a/ipc/glue/BackgroundChildImpl.cpp b/ipc/glue/BackgroundChildImpl.cpp index 718f965e3bfc..3f6cd45f86ce 100644 --- a/ipc/glue/BackgroundChildImpl.cpp +++ b/ipc/glue/BackgroundChildImpl.cpp @@ -219,6 +219,26 @@ BackgroundChildImpl::DeallocPBackgroundIndexedDBUtilsChild( return true; } +BackgroundChildImpl::PBackgroundLocalStorageCacheChild* +BackgroundChildImpl::AllocPBackgroundLocalStorageCacheChild( + const PrincipalInfo& aPrincipalInfo, + const nsCString& aOriginKey, + const uint32_t& aPrivateBrowsingId) +{ + MOZ_CRASH("PBackgroundLocalStorageChild actors should be manually " + "constructed!"); +} + +bool +BackgroundChildImpl::DeallocPBackgroundLocalStorageCacheChild( + PBackgroundLocalStorageCacheChild* aActor) +{ + MOZ_ASSERT(aActor); + + delete aActor; + return true; +} + BackgroundChildImpl::PBackgroundStorageChild* BackgroundChildImpl::AllocPBackgroundStorageChild(const nsString& aProfilePath) { @@ -715,32 +735,6 @@ BackgroundChildImpl::DeallocPServiceWorkerRegistrationChild(PServiceWorkerRegist return dom::DeallocServiceWorkerRegistrationChild(aActor); } -mozilla::ipc::IPCResult -BackgroundChildImpl::RecvDispatchLocalStorageChange( - const nsString& aDocumentURI, - const nsString& aKey, - const nsString& aOldValue, - const nsString& aNewValue, - const PrincipalInfo& aPrincipalInfo, - const bool& aIsPrivate) -{ - if (!NS_IsMainThread()) { - return IPC_OK(); - } - - nsresult rv; - nsCOMPtr principal = - PrincipalInfoToPrincipal(aPrincipalInfo, &rv); - if (NS_WARN_IF(NS_FAILED(rv))) { - return IPC_FAIL_NO_REASON(this); - } - - LocalStorage::DispatchStorageEvent(aDocumentURI, aKey, aOldValue, aNewValue, - principal, aIsPrivate, nullptr, true); - - return IPC_OK(); -} - bool BackgroundChildImpl::GetMessageSchedulerGroups(const Message& aMsg, SchedulerGroupSet& aGroups) { diff --git a/ipc/glue/BackgroundChildImpl.h b/ipc/glue/BackgroundChildImpl.h index 2ed022e34f23..325a9666416c 100644 --- a/ipc/glue/BackgroundChildImpl.h +++ b/ipc/glue/BackgroundChildImpl.h @@ -70,6 +70,17 @@ protected: DeallocPBackgroundIndexedDBUtilsChild(PBackgroundIndexedDBUtilsChild* aActor) override; + virtual PBackgroundLocalStorageCacheChild* + AllocPBackgroundLocalStorageCacheChild(const PrincipalInfo& aPrincipalInfo, + const nsCString& aOriginKey, + const uint32_t& aPrivateBrowsingId) + override; + + virtual bool + DeallocPBackgroundLocalStorageCacheChild( + PBackgroundLocalStorageCacheChild* aActor) + override; + virtual PBackgroundStorageChild* AllocPBackgroundStorageChild(const nsString& aProfilePath) override; @@ -227,14 +238,6 @@ protected: virtual bool DeallocPHttpBackgroundChannelChild(PHttpBackgroundChannelChild* aActor) override; - virtual mozilla::ipc::IPCResult - RecvDispatchLocalStorageChange(const nsString& aDocumentURI, - const nsString& aKey, - const nsString& aOldValue, - const nsString& aNewValue, - const PrincipalInfo& aPrincipalInfo, - const bool& aIsPrivate) override; - bool GetMessageSchedulerGroups(const Message& aMsg, SchedulerGroupSet& aGroups) override; diff --git a/ipc/glue/BackgroundParentImpl.cpp b/ipc/glue/BackgroundParentImpl.cpp index ad2920f4321b..a725e6efb495 100644 --- a/ipc/glue/BackgroundParentImpl.cpp +++ b/ipc/glue/BackgroundParentImpl.cpp @@ -252,6 +252,52 @@ BackgroundParentImpl::RecvFlushPendingFileDeletions() return IPC_OK(); } +BackgroundParentImpl::PBackgroundLocalStorageCacheParent* +BackgroundParentImpl::AllocPBackgroundLocalStorageCacheParent( + const PrincipalInfo& aPrincipalInfo, + const nsCString& aOriginKey, + const uint32_t& aPrivateBrowsingId) +{ + AssertIsInMainProcess(); + AssertIsOnBackgroundThread(); + + return + mozilla::dom::AllocPBackgroundLocalStorageCacheParent(aPrincipalInfo, + aOriginKey, + aPrivateBrowsingId); +} + +mozilla::ipc::IPCResult +BackgroundParentImpl::RecvPBackgroundLocalStorageCacheConstructor( + PBackgroundLocalStorageCacheParent* aActor, + const PrincipalInfo& aPrincipalInfo, + const nsCString& aOriginKey, + const uint32_t& aPrivateBrowsingId) +{ + AssertIsInMainProcess(); + AssertIsOnBackgroundThread(); + MOZ_ASSERT(aActor); + + return + mozilla::dom::RecvPBackgroundLocalStorageCacheConstructor( + this, + aActor, + aPrincipalInfo, + aOriginKey, + aPrivateBrowsingId); +} + +bool +BackgroundParentImpl::DeallocPBackgroundLocalStorageCacheParent( + PBackgroundLocalStorageCacheParent* aActor) +{ + AssertIsInMainProcess(); + AssertIsOnBackgroundThread(); + MOZ_ASSERT(aActor); + + return mozilla::dom::DeallocPBackgroundLocalStorageCacheParent(aActor); +} + auto BackgroundParentImpl::AllocPBackgroundStorageParent(const nsString& aProfilePath) -> PBackgroundStorageParent* @@ -285,34 +331,6 @@ BackgroundParentImpl::DeallocPBackgroundStorageParent( return mozilla::dom::DeallocPBackgroundStorageParent(aActor); } -mozilla::ipc::IPCResult -BackgroundParentImpl::RecvBroadcastLocalStorageChange( - const nsString& aDocumentURI, - const nsString& aKey, - const nsString& aOldValue, - const nsString& aNewValue, - const PrincipalInfo& aPrincipalInfo, - const bool& aIsPrivate) -{ - // Let's inform the StorageActivityService about this change. - dom::StorageActivityService::SendActivity(aPrincipalInfo); - - nsTArray liveActorArray; - if (NS_WARN_IF(!BackgroundParent::GetLiveActorArray(this, liveActorArray))) { - return IPC_FAIL_NO_REASON(this); - } - - for (auto* liveActor : liveActorArray) { - if (liveActor != this) { - Unused << liveActor->SendDispatchLocalStorageChange( - nsString(aDocumentURI), nsString(aKey), nsString(aOldValue), - nsString(aNewValue), aPrincipalInfo, aIsPrivate); - } - } - - return IPC_OK(); -} - PPendingIPCBlobParent* BackgroundParentImpl::AllocPPendingIPCBlobParent(const IPCBlob& aBlob) { diff --git a/ipc/glue/BackgroundParentImpl.h b/ipc/glue/BackgroundParentImpl.h index 6185c42821ef..577ca14fc392 100644 --- a/ipc/glue/BackgroundParentImpl.h +++ b/ipc/glue/BackgroundParentImpl.h @@ -63,6 +63,25 @@ protected: virtual mozilla::ipc::IPCResult RecvFlushPendingFileDeletions() override; + virtual PBackgroundLocalStorageCacheParent* + AllocPBackgroundLocalStorageCacheParent(const PrincipalInfo& aPrincipalInfo, + const nsCString& aOriginKey, + const uint32_t& aPrivateBrowsingId) + override; + + virtual mozilla::ipc::IPCResult + RecvPBackgroundLocalStorageCacheConstructor( + PBackgroundLocalStorageCacheParent* aActor, + const PrincipalInfo& aPrincipalInfo, + const nsCString& aOriginKey, + const uint32_t& aPrivateBrowsingId) + override; + + virtual bool + DeallocPBackgroundLocalStorageCacheParent( + PBackgroundLocalStorageCacheParent* aActor) + override; + virtual PBackgroundStorageParent* AllocPBackgroundStorageParent(const nsString& aProfilePath) override; @@ -73,14 +92,6 @@ protected: virtual bool DeallocPBackgroundStorageParent(PBackgroundStorageParent* aActor) override; - virtual mozilla::ipc::IPCResult - RecvBroadcastLocalStorageChange(const nsString& aDocumentURI, - const nsString& aKey, - const nsString& aOldValue, - const nsString& aNewValue, - const PrincipalInfo& aPrincipalInfo, - const bool& aIsPrivate) override; - virtual PPendingIPCBlobParent* AllocPPendingIPCBlobParent(const IPCBlob& aBlob) override; diff --git a/ipc/glue/GeckoChildProcessHost.cpp b/ipc/glue/GeckoChildProcessHost.cpp index f032800f701c..da4409a0e41e 100644 --- a/ipc/glue/GeckoChildProcessHost.cpp +++ b/ipc/glue/GeckoChildProcessHost.cpp @@ -1242,7 +1242,7 @@ GeckoChildProcessHost::LaunchAndroidService(const char* type, const base::file_handle_mapping_vector& fds_to_remap, ProcessHandle* process_handle) { - MOZ_RELEASE_ASSERT((2 <= fds_to_remap.size()) && (fds_to_remap.size() <= 4)); + MOZ_RELEASE_ASSERT((2 <= fds_to_remap.size()) && (fds_to_remap.size() <= 5)); JNIEnv* const env = mozilla::jni::GetEnvForThread(); MOZ_ASSERT(env); @@ -1258,18 +1258,19 @@ GeckoChildProcessHost::LaunchAndroidService(const char* type, // which they append to fds_to_remap. There must be a better way to do it. // See bug 1440207. int32_t prefsFd = fds_to_remap[0].first; - int32_t ipcFd = fds_to_remap[1].first; + int32_t prefMapFd = fds_to_remap[1].first; + int32_t ipcFd = fds_to_remap[2].first; int32_t crashFd = -1; int32_t crashAnnotationFd = -1; - if (fds_to_remap.size() == 3) { - crashAnnotationFd = fds_to_remap[2].first; - } if (fds_to_remap.size() == 4) { - crashFd = fds_to_remap[2].first; crashAnnotationFd = fds_to_remap[3].first; } + if (fds_to_remap.size() == 5) { + crashFd = fds_to_remap[3].first; + crashAnnotationFd = fds_to_remap[4].first; + } - int32_t handle = java::GeckoProcessManager::Start(type, jargs, prefsFd, ipcFd, crashFd, crashAnnotationFd); + int32_t handle = java::GeckoProcessManager::Start(type, jargs, prefsFd, prefMapFd, ipcFd, crashFd, crashAnnotationFd); if (process_handle) { *process_handle = handle; diff --git a/ipc/glue/PBackground.ipdl b/ipc/glue/PBackground.ipdl index a7480e1372ad..3a4a790db090 100644 --- a/ipc/glue/PBackground.ipdl +++ b/ipc/glue/PBackground.ipdl @@ -5,6 +5,7 @@ include protocol PAsmJSCacheEntry; include protocol PBackgroundIDBFactory; include protocol PBackgroundIndexedDBUtils; +include protocol PBackgroundLocalStorageCache; include protocol PBackgroundStorage; include protocol PBackgroundTest; include protocol PBroadcastChannel; @@ -65,6 +66,7 @@ sync protocol PBackground manages PAsmJSCacheEntry; manages PBackgroundIDBFactory; manages PBackgroundIndexedDBUtils; + manages PBackgroundLocalStorageCache; manages PBackgroundStorage; manages PBackgroundTest; manages PBroadcastChannel; @@ -106,14 +108,11 @@ parent: // Use only for testing! async FlushPendingFileDeletions(); - async PBackgroundStorage(nsString profilePath); + async PBackgroundLocalStorageCache(PrincipalInfo principalInfo, + nsCString originKey, + uint32_t privateBrowsingId); - async BroadcastLocalStorageChange(nsString documentURI, - nsString key, - nsString oldValue, - nsString newValue, - PrincipalInfo principalInfo, - bool isPrivate); + async PBackgroundStorage(nsString profilePath); async PVsync(); @@ -175,13 +174,6 @@ child: async PPendingIPCBlob(IPCBlob blob); - async DispatchLocalStorageChange(nsString documentURI, - nsString key, - nsString oldValue, - nsString newValue, - PrincipalInfo principalInfo, - bool isPrivate); - both: // PIPCBlobInputStream is created on the parent side only if the child starts // a migration. diff --git a/js/src/vm/Monitor.h b/js/src/vm/Monitor.h index c5ce9b843110..b8ec98da68f9 100644 --- a/js/src/vm/Monitor.h +++ b/js/src/vm/Monitor.h @@ -48,7 +48,7 @@ class AutoLockMonitor : public LockGuard { } bool isFor(Monitor& other) const { - return monitor.lock_ == other.lock_; + return &monitor.lock_ == &other.lock_; } void wait(ConditionVariable& condVar) { @@ -93,7 +93,7 @@ class AutoUnlockMonitor } bool isFor(Monitor& other) const { - return monitor.lock_ == other.lock_; + return &monitor.lock_ == &other.lock_; } }; diff --git a/layout/xul/nsXULTooltipListener.cpp b/layout/xul/nsXULTooltipListener.cpp index 7cea95ae791e..0a04dcce631f 100644 --- a/layout/xul/nsXULTooltipListener.cpp +++ b/layout/xul/nsXULTooltipListener.cpp @@ -102,7 +102,13 @@ nsXULTooltipListener::MouseOut(Event* aEvent) // hide the tooltip if (currentTooltip) { // which node did the mouse leave? - nsCOMPtr targetNode = do_QueryInterface(aEvent->GetTarget()); + EventTarget* eventTarget = aEvent->GetComposedTarget(); + nsCOMPtr content = do_QueryInterface(eventTarget); + if (content && !content->GetContainingShadow()) { + eventTarget = aEvent->GetTarget(); + } + + nsCOMPtr targetNode = do_QueryInterface(eventTarget); nsXULPopupManager* pm = nsXULPopupManager::GetInstance(); if (pm) { @@ -173,7 +179,11 @@ nsXULTooltipListener::MouseMove(Event* aEvent) // showing and the tooltip hasn't been displayed since the mouse entered // the node, then start the timer to show the tooltip. if (!currentTooltip && !mTooltipShownOnce) { - nsCOMPtr eventTarget = aEvent->GetTarget(); + nsCOMPtr eventTarget = aEvent->GetComposedTarget(); + nsCOMPtr content = do_QueryInterface(eventTarget); + if (content && !content->GetContainingShadow()) { + eventTarget = aEvent->GetTarget(); + } // don't show tooltips attached to elements outside of a menu popup // when hovering over an element inside it. The popupsinherittooltip diff --git a/mobile/android/base/java/org/mozilla/gecko/customtabs/CustomTabsActivity.java b/mobile/android/base/java/org/mozilla/gecko/customtabs/CustomTabsActivity.java index 7969b704ddc3..752f11cc8027 100644 --- a/mobile/android/base/java/org/mozilla/gecko/customtabs/CustomTabsActivity.java +++ b/mobile/android/base/java/org/mozilla/gecko/customtabs/CustomTabsActivity.java @@ -59,6 +59,7 @@ import org.mozilla.gecko.webapps.WebApps; import org.mozilla.gecko.widget.ActionModePresenter; import org.mozilla.gecko.widget.GeckoPopupMenu; import org.mozilla.geckoview.GeckoResponse; +import org.mozilla.geckoview.GeckoResult; import org.mozilla.geckoview.GeckoRuntime; import org.mozilla.geckoview.GeckoSession; import org.mozilla.geckoview.GeckoSessionSettings; @@ -600,21 +601,18 @@ public class CustomTabsActivity extends AppCompatActivity } @Override - public void onLoadRequest(final GeckoSession session, final String urlStr, - final int target, - final int flags, - final GeckoResponse response) { + public GeckoResult onLoadRequest(final GeckoSession session, final String urlStr, + final int target, + final int flags) { if (target != GeckoSession.NavigationDelegate.TARGET_WINDOW_NEW) { - response.respond(false); - return; + return GeckoResult.fromValue(false); } final Uri uri = Uri.parse(urlStr); if (uri == null) { // We can't handle this, so deny it. Log.w(LOGTAG, "Failed to parse URL for navigation: " + urlStr); - response.respond(true); - return; + return GeckoResult.fromValue(true); } // Always use Fennec for these schemes. @@ -639,12 +637,11 @@ public class CustomTabsActivity extends AppCompatActivity } } - response.respond(true); + return GeckoResult.fromValue(true); } @Override - public void onNewSession(final GeckoSession session, final String uri, - final GeckoResponse response) { + public GeckoResult onNewSession(final GeckoSession session, final String uri) { // We should never get here because we abort loads that need a new session in onLoadRequest() throw new IllegalStateException("Unexpected new session"); } diff --git a/mobile/android/base/java/org/mozilla/gecko/webapps/WebAppActivity.java b/mobile/android/base/java/org/mozilla/gecko/webapps/WebAppActivity.java index b01658b87ad7..de35f814043c 100644 --- a/mobile/android/base/java/org/mozilla/gecko/webapps/WebAppActivity.java +++ b/mobile/android/base/java/org/mozilla/gecko/webapps/WebAppActivity.java @@ -39,6 +39,7 @@ import org.mozilla.gecko.util.ActivityUtils; import org.mozilla.gecko.util.ColorUtil; import org.mozilla.gecko.widget.ActionModePresenter; import org.mozilla.geckoview.GeckoResponse; +import org.mozilla.geckoview.GeckoResult; import org.mozilla.geckoview.GeckoRuntime; import org.mozilla.geckoview.GeckoSession; import org.mozilla.geckoview.GeckoSessionSettings; @@ -383,29 +384,25 @@ public class WebAppActivity extends AppCompatActivity } @Override - public void onLoadRequest(final GeckoSession session, final String urlStr, - final int target, - final int flags, - final GeckoResponse response) { + public GeckoResult onLoadRequest(final GeckoSession session, final String urlStr, + final int target, + final int flags) { final Uri uri = Uri.parse(urlStr); if (uri == null) { // We can't really handle this, so deny it? Log.w(LOGTAG, "Failed to parse URL for navigation: " + urlStr); - response.respond(true); - return; + return GeckoResult.fromValue(true); } if (mManifest.isInScope(uri) && target != TARGET_WINDOW_NEW) { // This is in scope and wants to load in the same frame, so // let Gecko handle it. - response.respond(false); - return; + return GeckoResult.fromValue(false); } if ("javascript".equals(uri.getScheme())) { // These URIs will fail the scope check but should still be loaded in the PWA. - response.respond(false); - return; + return GeckoResult.fromValue(false); } if ("http".equals(uri.getScheme()) || "https".equals(uri.getScheme()) || @@ -433,12 +430,12 @@ public class WebAppActivity extends AppCompatActivity Log.w(LOGTAG, "No activity handler found for: " + urlStr); } } - response.respond(true); + + return GeckoResult.fromValue(true); } @Override - public void onNewSession(final GeckoSession session, final String uri, - final GeckoResponse response) { + public GeckoResult onNewSession(final GeckoSession session, final String uri) { // We should never get here because we abort loads that need a new session in onLoadRequest() throw new IllegalStateException("Unexpected new session"); } diff --git a/mobile/android/chrome/geckoview/GeckoViewContent.js b/mobile/android/chrome/geckoview/GeckoViewContent.js index 36e826ac3cf6..a1e65f34693c 100644 --- a/mobile/android/chrome/geckoview/GeckoViewContent.js +++ b/mobile/android/chrome/geckoview/GeckoViewContent.js @@ -158,8 +158,18 @@ class GeckoViewContent extends GeckoViewContentModule { // Short circuit and return the pending state if we're in the process of restoring sendAsyncMessage("GeckoView:SaveStateFinish", {state: JSON.stringify(this._savedState), id: aMsg.data.id}); } else { - let state = this.collectSessionState(); - sendAsyncMessage("GeckoView:SaveStateFinish", {state: JSON.stringify(state), id: aMsg.data.id}); + try { + let state = this.collectSessionState(); + sendAsyncMessage("GeckoView:SaveStateFinish", { + state: state ? JSON.stringify(state) : null, + id: aMsg.data.id + }); + } catch (e) { + sendAsyncMessage("GeckoView:SaveStateFinish", { + error: e.message, + id: aMsg.data.id + }); + } } break; diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/ContentDelegateTest.kt b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/ContentDelegateTest.kt index f5d23340e28d..2ad3c3105b75 100644 --- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/ContentDelegateTest.kt +++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/ContentDelegateTest.kt @@ -4,7 +4,7 @@ package org.mozilla.geckoview.test -import org.mozilla.geckoview.GeckoResponse +import org.mozilla.geckoview.GeckoResult import org.mozilla.geckoview.GeckoSession import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.AssertCalled import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.IgnoreCrash @@ -12,7 +12,9 @@ import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.ReuseSession import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.WithDevToolsAPI import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.WithDisplay import org.mozilla.geckoview.test.util.Callbacks +import org.mozilla.geckoview.test.util.UiThreadUtils +import android.os.Looper import android.support.test.filters.MediumTest import android.support.test.runner.AndroidJUnit4 import org.hamcrest.Matchers.* @@ -20,6 +22,8 @@ import org.junit.Assume.assumeThat import org.junit.Test import org.junit.runner.RunWith +import kotlin.concurrent.thread + @RunWith(AndroidJUnit4::class) @MediumTest class ContentDelegateTest : BaseSessionTest() { @@ -43,13 +47,13 @@ class ContentDelegateTest : BaseSessionTest() { @AssertCalled(count = 2) override fun onLoadRequest(session: GeckoSession, uri: String, - where: Int, flags: Int, - response: GeckoResponse) { - response.respond(false) + where: Int, flags: Int): GeckoResult? { + return null } @AssertCalled(false) - override fun onNewSession(session: GeckoSession, uri: String, response: GeckoResponse) { + override fun onNewSession(session: GeckoSession, uri: String): GeckoResult? { + return null } @AssertCalled(count = 1) @@ -155,4 +159,29 @@ class ContentDelegateTest : BaseSessionTest() { mainSession.evaluateJS("window.scrollY") as Double, closeTo(100.0, .5)) } + + @Test fun saveStateSync() { + val startUri = createTestUrl(SAVE_STATE_PATH) + mainSession.loadUri(startUri) + sessionRule.waitForPageStop() + + var worker = thread { + Looper.prepare() + + var thread = Thread.currentThread() + mainSession.saveState().then { _: GeckoSession.SessionState? -> + assertThat("We should be on the worker thread", Thread.currentThread(), + equalTo(thread)) + Looper.myLooper().quit() + null + } + + Looper.loop() + } + + worker.join(sessionRule.timeoutMillis) + if (worker.isAlive) { + throw UiThreadUtils.TimeoutException("Timed out") + } + } } diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/GeckoResultTest.java b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/GeckoResultTest.java index 54c822122a52..954730c0e8e1 100644 --- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/GeckoResultTest.java +++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/GeckoResultTest.java @@ -56,6 +56,13 @@ public class GeckoResultTest { mDone = false; } + @Test(expected = RuntimeException.class) + public void createWithoutLooper() { + // Without @UiThreadTest this will be run in a worker + // thread that does not have a Looper. + new GeckoResult(); + } + @Test @UiThreadTest public void thenWithResult() { @@ -95,12 +102,18 @@ public class GeckoResultTest { @Test @UiThreadTest - public void testEquals() { - final GeckoResult result = GeckoResult.fromValue(42); - final GeckoResult result2 = new GeckoResult<>(result); + public void testCopy() { + final GeckoResult result = new GeckoResult<>(GeckoResult.fromValue(42)); + result.then(new OnValueListener() { + @Override + public GeckoResult onValue(Integer value) throws Throwable { + assertThat("Value should match", value, equalTo(42)); + done(); + return null; + } + }); - assertThat("Results should be equal", result, equalTo(result2)); - assertThat("Hashcode should be equal", result.hashCode(), equalTo(result2.hashCode())); + waitUntilDone(); } @Test(expected = IllegalStateException.class) @@ -159,6 +172,33 @@ public class GeckoResultTest { waitUntilDone(); } + @Test + @UiThreadTest + public void dispatchOnInitialThread() throws InterruptedException { + final Thread thread = new Thread(new Runnable() { + @Override + public void run() { + Looper.prepare(); + final Thread dispatchThread = Thread.currentThread(); + + GeckoResult.fromValue(42).then(new OnValueListener() { + @Override + public GeckoResult onValue(Integer value) throws Throwable { + assertThat("Thread should match", Thread.currentThread(), + equalTo(dispatchThread)); + Looper.myLooper().quit(); + return null; + } + }); + + Looper.loop(); + } + }); + + thread.start(); + thread.join(); + } + @Test @UiThreadTest public void completeExceptionallyThreaded() { diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/NavigationDelegateTest.kt b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/NavigationDelegateTest.kt index b049c93bff56..db9bbc21c102 100644 --- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/NavigationDelegateTest.kt +++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/NavigationDelegateTest.kt @@ -4,7 +4,7 @@ package org.mozilla.geckoview.test -import org.mozilla.geckoview.GeckoResponse +import org.mozilla.geckoview.GeckoResult import org.mozilla.geckoview.GeckoSession import org.mozilla.geckoview.GeckoSessionSettings import org.mozilla.geckoview.GeckoSession.TrackingProtectionDelegate; @@ -18,6 +18,7 @@ import org.mozilla.geckoview.test.util.Callbacks import android.support.test.filters.MediumTest import android.support.test.runner.AndroidJUnit4 import org.hamcrest.Matchers.* +import org.junit.Ignore import org.junit.Test import org.junit.runner.RunWith @@ -101,16 +102,14 @@ class NavigationDelegateTest : BaseSessionTest() { sessionRule.forCallbacksDuringWait(object : Callbacks.NavigationDelegate { @AssertCalled(count = 1, order = [1]) override fun onLoadRequest(session: GeckoSession, uri: String, - where: Int, - flags: Int, - response: GeckoResponse) { + where: Int, flags: Int): GeckoResult? { assertThat("Session should not be null", session, notNullValue()) assertThat("URI should not be null", uri, notNullValue()) assertThat("URI should match", uri, endsWith(HELLO_HTML_PATH)) assertThat("Where should not be null", where, notNullValue()) assertThat("Where should match", where, equalTo(GeckoSession.NavigationDelegate.TARGET_WINDOW_CURRENT)) - response.respond(false) + return null } @AssertCalled(count = 1, order = [2]) @@ -133,8 +132,8 @@ class NavigationDelegateTest : BaseSessionTest() { } @AssertCalled(false) - override fun onNewSession(session: GeckoSession, uri: String, - response: GeckoResponse) { + override fun onNewSession(session: GeckoSession, uri: String): GeckoResult? { + return null } }) } @@ -296,13 +295,11 @@ class NavigationDelegateTest : BaseSessionTest() { sessionRule.forCallbacksDuringWait(object : Callbacks.NavigationDelegate { @AssertCalled(count = 1, order = [1]) override fun onLoadRequest(session: GeckoSession, uri: String, - where: Int, - flags: Int, - response: GeckoResponse) { + where: Int, flags: Int): GeckoResult? { assertThat("URI should match", uri, endsWith(HELLO_HTML_PATH)) assertThat("Where should match", where, equalTo(GeckoSession.NavigationDelegate.TARGET_WINDOW_CURRENT)) - response.respond(false) + return null } @AssertCalled(count = 1, order = [2]) @@ -321,8 +318,8 @@ class NavigationDelegateTest : BaseSessionTest() { } @AssertCalled(false) - override fun onNewSession(session: GeckoSession, uri: String, - response: GeckoResponse) { + override fun onNewSession(session: GeckoSession, uri: String): GeckoResult? { + return null } }) } @@ -347,13 +344,11 @@ class NavigationDelegateTest : BaseSessionTest() { sessionRule.forCallbacksDuringWait(object : Callbacks.NavigationDelegate { @AssertCalled(count = 1, order = [1]) override fun onLoadRequest(session: GeckoSession, uri: String, - where: Int, - flags: Int, - response: GeckoResponse) { + where: Int, flags: Int): GeckoResult? { assertThat("URI should match", uri, endsWith(HELLO_HTML_PATH)) assertThat("Where should match", where, equalTo(GeckoSession.NavigationDelegate.TARGET_WINDOW_CURRENT)) - response.respond(false) + return null } @AssertCalled(count = 1, order = [2]) @@ -372,8 +367,8 @@ class NavigationDelegateTest : BaseSessionTest() { } @AssertCalled(false) - override fun onNewSession(session: GeckoSession, uri: String, - response: GeckoResponse) { + override fun onNewSession(session: GeckoSession, uri: String): GeckoResult? { + return null } }) @@ -383,13 +378,11 @@ class NavigationDelegateTest : BaseSessionTest() { sessionRule.forCallbacksDuringWait(object : Callbacks.NavigationDelegate { @AssertCalled(count = 1, order = [1]) override fun onLoadRequest(session: GeckoSession, uri: String, - where: Int, - flags: Int, - response: GeckoResponse) { + where: Int, flags: Int): GeckoResult? { assertThat("URI should match", uri, endsWith(HELLO2_HTML_PATH)) assertThat("Where should match", where, equalTo(GeckoSession.NavigationDelegate.TARGET_WINDOW_CURRENT)) - response.respond(false) + return null } @AssertCalled(count = 1, order = [2]) @@ -408,8 +401,8 @@ class NavigationDelegateTest : BaseSessionTest() { } @AssertCalled(false) - override fun onNewSession(session: GeckoSession, uri: String, - response: GeckoResponse) { + override fun onNewSession(session: GeckoSession, uri: String): GeckoResult? { + return null } }) } @@ -418,10 +411,8 @@ class NavigationDelegateTest : BaseSessionTest() { sessionRule.delegateDuringNextWait(object : Callbacks.NavigationDelegate { @AssertCalled(count = 2) override fun onLoadRequest(session: GeckoSession, uri: String, - where: Int, - flags: Int, - response: GeckoResponse) { - response.respond(uri.endsWith(HELLO_HTML_PATH)) + where: Int, flags: Int): GeckoResult { + return GeckoResult.fromValue(uri.endsWith(HELLO_HTML_PATH)) } }) @@ -454,15 +445,18 @@ class NavigationDelegateTest : BaseSessionTest() { sessionRule.session.waitUntilCalled(object : Callbacks.NavigationDelegate { @AssertCalled(count = 1, order = [1]) - override fun onLoadRequest(session: GeckoSession, uri: String, where: Int, flags: Int, response: GeckoResponse) { + override fun onLoadRequest(session: GeckoSession, uri: String, + where: Int, flags: Int): GeckoResult? { assertThat("URI should be correct", uri, endsWith(NEW_SESSION_CHILD_HTML_PATH)) assertThat("Where should be correct", where, equalTo(GeckoSession.NavigationDelegate.TARGET_WINDOW_NEW)) + return null } @AssertCalled(count = 1, order = [2]) - override fun onNewSession(session: GeckoSession, uri: String, response: GeckoResponse) { + override fun onNewSession(session: GeckoSession, uri: String): GeckoResult? { assertThat("URI should be correct", uri, endsWith(NEW_SESSION_CHILD_HTML_PATH)) + return null } }) } @@ -481,15 +475,18 @@ class NavigationDelegateTest : BaseSessionTest() { // We get two onLoadRequest calls for the link click, // one when loading the URL and one when opening a new window. @AssertCalled(count = 2, order = [1]) - override fun onLoadRequest(session: GeckoSession, uri: String, where: Int, flags: Int, response: GeckoResponse) { + override fun onLoadRequest(session: GeckoSession, uri: String, + where: Int, flags: Int): GeckoResult? { assertThat("URI should be correct", uri, endsWith(NEW_SESSION_CHILD_HTML_PATH)) assertThat("Where should be correct", where, equalTo(GeckoSession.NavigationDelegate.TARGET_WINDOW_NEW)) + return null } @AssertCalled(count = 1, order = [2]) - override fun onNewSession(session: GeckoSession, uri: String, response: GeckoResponse) { + override fun onNewSession(session: GeckoSession, uri: String): GeckoResult? { assertThat("URI should be correct", uri, endsWith(NEW_SESSION_CHILD_HTML_PATH)) + return null } }) } @@ -499,8 +496,8 @@ class NavigationDelegateTest : BaseSessionTest() { sessionRule.session.delegateDuringNextWait(object : Callbacks.NavigationDelegate { @AssertCalled(count = 1) - override fun onNewSession(session: GeckoSession, uri: String, response: GeckoResponse) { - response.respond(newSession) + override fun onNewSession(session: GeckoSession, uri: String): GeckoResult { + return GeckoResult.fromValue(newSession) } }) @@ -574,9 +571,10 @@ class NavigationDelegateTest : BaseSessionTest() { sessionRule.session.waitForPageStop() sessionRule.session.delegateDuringNextWait(object : Callbacks.NavigationDelegate { - override fun onLoadRequest(session: GeckoSession, uri: String, where: Int, flags: Int, response: GeckoResponse) { + override fun onLoadRequest(session: GeckoSession, uri: String, + where: Int, flags: Int): GeckoResult { // Pretend we handled the target="_blank" link click. - response.respond(uri.endsWith(NEW_SESSION_CHILD_HTML_PATH)) + return GeckoResult.fromValue(uri.endsWith(NEW_SESSION_CHILD_HTML_PATH)) } }) @@ -588,19 +586,22 @@ class NavigationDelegateTest : BaseSessionTest() { // Assert that onNewSession was not called for the link click. sessionRule.session.forCallbacksDuringWait(object : Callbacks.NavigationDelegate { @AssertCalled(count = 2) - override fun onLoadRequest(session: GeckoSession, uri: String, where: Int, flags: Int, response: GeckoResponse) { + override fun onLoadRequest(session: GeckoSession, uri: String, + where: Int, flags: Int): GeckoResult? { assertThat("URI must match", uri, endsWith(forEachCall(NEW_SESSION_CHILD_HTML_PATH, NEW_SESSION_HTML_PATH))) + return null } @AssertCalled(count = 0) - override fun onNewSession(session: GeckoSession, uri: String, response: GeckoResponse) { + override fun onNewSession(session: GeckoSession, uri: String): GeckoResult? { + return null } }) } @WithDevToolsAPI - @Test(expected = IllegalArgumentException::class) + @Test(expected = GeckoResult.UncaughtException::class) fun onNewSession_doesNotAllowOpened() { // Disable popup blocker. sessionRule.setPrefsUntilTestEnd(mapOf("dom.disable_open_during_load" to false)) @@ -610,8 +611,8 @@ class NavigationDelegateTest : BaseSessionTest() { sessionRule.session.delegateDuringNextWait(object : Callbacks.NavigationDelegate { @AssertCalled(count = 1) - override fun onNewSession(session: GeckoSession, uri: String, response: GeckoResponse) { - response.respond(sessionRule.createOpenSession()) + override fun onNewSession(session: GeckoSession, uri: String): GeckoResult { + return GeckoResult.fromValue(sessionRule.createOpenSession()) } }) diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/ProgressDelegateTest.kt b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/ProgressDelegateTest.kt index 0f5dd2358e15..83c5983a1cd8 100644 --- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/ProgressDelegateTest.kt +++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/ProgressDelegateTest.kt @@ -4,7 +4,7 @@ package org.mozilla.geckoview.test -import org.mozilla.geckoview.GeckoResponse +import org.mozilla.geckoview.GeckoResult import org.mozilla.geckoview.GeckoSession import org.mozilla.geckoview.test.rule.GeckoSessionTestRule.AssertCalled import org.mozilla.geckoview.test.util.Callbacks @@ -62,15 +62,13 @@ class ProgressDelegateTest : BaseSessionTest() { sessionRule.forCallbacksDuringWait(object : Callbacks.ProgressDelegate, Callbacks.NavigationDelegate { @AssertCalled(count = 2) override fun onLoadRequest(session: GeckoSession, uri: String, - where: Int, - flags: Int, - response: GeckoResponse) { + where: Int, flags: Int): GeckoResult? { if (sessionRule.currentCall.counter == 1) { assertThat("URI should be " + testUri, uri, equalTo(testUri)); } else { assertThat("URI should be about:neterror", uri, startsWith("about:neterror")); } - response.respond(false) + return null } @AssertCalled(count = 1) diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/TestRunnerActivity.java b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/TestRunnerActivity.java index b842826e022b..2657569293a8 100644 --- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/TestRunnerActivity.java +++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/TestRunnerActivity.java @@ -7,6 +7,7 @@ package org.mozilla.geckoview.test; import org.mozilla.gecko.gfx.GeckoDisplay; import org.mozilla.geckoview.GeckoResponse; +import org.mozilla.geckoview.GeckoResult; import org.mozilla.geckoview.GeckoSession; import org.mozilla.geckoview.GeckoSessionSettings; import org.mozilla.geckoview.GeckoView; @@ -50,16 +51,15 @@ public class TestRunnerActivity extends Activity { } @Override - public void onLoadRequest(GeckoSession session, String uri, int target, - int flags, - GeckoResponse response) { + public GeckoResult onLoadRequest(GeckoSession session, String uri, int target, + int flags) { // Allow Gecko to load all URIs - response.respond(false); + return GeckoResult.fromValue(false); } @Override - public void onNewSession(GeckoSession session, String uri, GeckoResponse response) { - response.respond(createBackgroundSession(session.getSettings())); + public GeckoResult onNewSession(GeckoSession session, String uri) { + return GeckoResult.fromValue(createBackgroundSession(session.getSettings())); } }; diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/rule/GeckoSessionTestRule.java b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/rule/GeckoSessionTestRule.java index 6fe32447b50e..7bbc6c1c57a0 100644 --- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/rule/GeckoSessionTestRule.java +++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/rule/GeckoSessionTestRule.java @@ -112,7 +112,7 @@ public class GeckoSessionTestRule extends UiThreadTestRule { sOnPageStop = GeckoSession.ProgressDelegate.class.getMethod( "onPageStop", GeckoSession.class, boolean.class); sOnNewSession = GeckoSession.NavigationDelegate.class.getMethod( - "onNewSession", GeckoSession.class, String.class, GeckoResponse.class); + "onNewSession", GeckoSession.class, String.class); sOnCrash = GeckoSession.ContentDelegate.class.getMethod( "onCrash", GeckoSession.class); } catch (final NoSuchMethodException e) { @@ -924,6 +924,15 @@ public class GeckoSessionTestRule extends UiThreadTestRule { return mErrorCollector; } + /** + * Get the current timeout value in milliseconds. + * + * @return The current timeout value in milliseconds. + */ + public long getTimeoutMillis() { + return mTimeoutMillis; + } + /** * Assert a condition with junit.Assert or an error collector. * @@ -1182,34 +1191,50 @@ public class GeckoSessionTestRule extends UiThreadTestRule { } } - if (call != null && sOnNewSession.equals(method)) { - // We're delegating an onNewSession call. - // Make sure we wait on the newly opened session, if any. - final GeckoSession oldSession = (GeckoSession) args[0]; - @SuppressWarnings("unchecked") - final GeckoResponse realResponse = - (GeckoResponse) args[2]; - args[2] = new GeckoResponse() { - @Override - public void respond(final GeckoSession newSession) { - realResponse.respond(newSession); - // `realResponse` has opened the session at this point, so wait on it. - if (oldSession.isOpen() && newSession != null) { - GeckoSessionTestRule.this.waitForOpenSession(newSession); - } - } - }; - } - + Object returnValue = null; try { mCurrentMethodCall = call; - return method.invoke((call != null) ? call.target + returnValue = method.invoke((call != null) ? call.target : Callbacks.Default.INSTANCE, args); } catch (final IllegalAccessException | InvocationTargetException e) { throw unwrapRuntimeException(e); } finally { mCurrentMethodCall = null; } + + if (call == null || returnValue == null || !sOnNewSession.equals(method)) { + return returnValue; + } + + // We're delegating an onNewSession call. + // Make sure we wait on the newly opened session, if any. + final GeckoSession oldSession = (GeckoSession) args[0]; + + @SuppressWarnings("unchecked") + final GeckoResult result = (GeckoResult)returnValue; + final GeckoResult tmpResult = new GeckoResult<>(); + result.then(new OnValueListener() { + @Override + public GeckoResult onValue(final GeckoSession newSession) throws Throwable { + tmpResult.complete(newSession); + + // GeckoSession has already hooked up its then() listener earlier, + // so ours will run after. We can wait for the session to + // open here. + tmpResult.then(new OnValueListener() { + @Override + public GeckoResult onValue(GeckoSession newSession) throws Throwable { + if (oldSession.isOpen() && newSession != null) { + GeckoSessionTestRule.this.waitForOpenSession(newSession); + } + return null; + } + }); + return null; + } + }); + + return tmpResult; } }; diff --git a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/util/Callbacks.kt b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/util/Callbacks.kt index 5667d131c734..c5c2aa9956f5 100644 --- a/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/util/Callbacks.kt +++ b/mobile/android/geckoview/src/androidTest/java/org/mozilla/geckoview/test/util/Callbacks.kt @@ -6,6 +6,7 @@ package org.mozilla.geckoview.test.util import org.mozilla.geckoview.GeckoResponse +import org.mozilla.geckoview.GeckoResult import org.mozilla.geckoview.GeckoSession import android.view.inputmethod.CursorAnchorInfo @@ -53,13 +54,12 @@ class Callbacks private constructor() { } override fun onLoadRequest(session: GeckoSession, uri: String, where: Int, - flags: Int, - response: GeckoResponse) { - response.respond(false) + flags: Int): GeckoResult? { + return null } - override fun onNewSession(session: GeckoSession, uri: String, response: GeckoResponse) { - response.respond(null) + override fun onNewSession(session: GeckoSession, uri: String): GeckoResult? { + return null; } } diff --git a/mobile/android/geckoview/src/main/aidl/org/mozilla/gecko/process/IChildProcess.aidl b/mobile/android/geckoview/src/main/aidl/org/mozilla/gecko/process/IChildProcess.aidl index c731a3d0cc0c..99e880b61ff5 100644 --- a/mobile/android/geckoview/src/main/aidl/org/mozilla/gecko/process/IChildProcess.aidl +++ b/mobile/android/geckoview/src/main/aidl/org/mozilla/gecko/process/IChildProcess.aidl @@ -12,7 +12,8 @@ import android.os.ParcelFileDescriptor; interface IChildProcess { int getPid(); boolean start(in IProcessManager procMan, in String[] args, in Bundle extras, int flags, - in ParcelFileDescriptor prefsPfd, in ParcelFileDescriptor ipcPfd, + in ParcelFileDescriptor prefsPfd, in ParcelFileDescriptor prefMapPfd, + in ParcelFileDescriptor ipcPfd, in ParcelFileDescriptor crashReporterPfd, in ParcelFileDescriptor crashAnnotationPfd); diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/CrashReporterService.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/CrashReporterService.java index dd039b155726..580694457df1 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/CrashReporterService.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/CrashReporterService.java @@ -308,6 +308,10 @@ public class CrashReporterService extends IntentService { OutputStream os = new GZIPOutputStream(conn.getOutputStream()); for (String key : extras.keySet()) { + if (key.equals(PAGE_URL_KEY)) { + continue; + } + if (!key.equals(SERVER_URL_KEY) && !key.equals(NOTES_KEY)) { sendPart(os, boundary, key, extras.get(key)); } diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoThread.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoThread.java index 076d7b92ee99..9abfd27986ce 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoThread.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/GeckoThread.java @@ -132,6 +132,7 @@ public class GeckoThread extends Thread { /* package */ static final String EXTRA_ARGS = "args"; private static final String EXTRA_PREFS_FD = "prefsFd"; + private static final String EXTRA_PREF_MAP_FD = "prefMapFd"; private static final String EXTRA_IPC_FD = "ipcFd"; private static final String EXTRA_CRASH_FD = "crashFd"; private static final String EXTRA_CRASH_ANNOTATION_FD = "crashAnnotationFd"; @@ -153,7 +154,8 @@ public class GeckoThread extends Thread { private synchronized boolean init(final GeckoProfile profile, final String[] args, final Bundle extras, final int flags, - final int prefsFd, final int ipcFd, + final int prefsFd, final int prefMapFd, + final int ipcFd, final int crashFd, final int crashAnnotationFd) { ThreadUtils.assertOnUiThread(); @@ -169,6 +171,7 @@ public class GeckoThread extends Thread { mExtras = (extras != null) ? new Bundle(extras) : new Bundle(3); mExtras.putInt(EXTRA_PREFS_FD, prefsFd); + mExtras.putInt(EXTRA_PREF_MAP_FD, prefMapFd); mExtras.putInt(EXTRA_IPC_FD, ipcFd); mExtras.putInt(EXTRA_CRASH_FD, crashFd); mExtras.putInt(EXTRA_CRASH_ANNOTATION_FD, crashAnnotationFd); @@ -181,18 +184,20 @@ public class GeckoThread extends Thread { public static boolean initMainProcess(final GeckoProfile profile, final String[] args, final Bundle extras, final int flags) { return INSTANCE.init(profile, args, extras, flags, /* fd */ -1, - /* fd */ -1, /* fd */ -1, /* fd */ -1); + /* fd */ -1, /* fd */ -1, /* fd */ -1, + /* fd */ -1); } public static boolean initChildProcess(final String[] args, final Bundle extras, final int flags, final int prefsFd, + final int prefMapFd, final int ipcFd, final int crashFd, final int crashAnnotationFd) { return INSTANCE.init(/* profile */ null, args, extras, flags, - prefsFd, ipcFd, crashFd, crashAnnotationFd); + prefsFd, prefMapFd, ipcFd, crashFd, crashAnnotationFd); } private static boolean canUseProfile(final Context context, final GeckoProfile profile, @@ -497,6 +502,7 @@ public class GeckoThread extends Thread { // And go. GeckoLoader.nativeRun(args, mExtras.getInt(EXTRA_PREFS_FD, -1), + mExtras.getInt(EXTRA_PREF_MAP_FD, -1), mExtras.getInt(EXTRA_IPC_FD, -1), mExtras.getInt(EXTRA_CRASH_FD, -1), mExtras.getInt(EXTRA_CRASH_ANNOTATION_FD, -1)); diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/mozglue/GeckoLoader.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/mozglue/GeckoLoader.java index 6ea25710f0b3..f04cb3644b2f 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/mozglue/GeckoLoader.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/mozglue/GeckoLoader.java @@ -456,7 +456,7 @@ public final class GeckoLoader { public static native boolean verifyCRCs(String apkName); // These methods are implemented in mozglue/android/APKOpen.cpp - public static native void nativeRun(String[] args, int prefsFd, int ipcFd, int crashFd, int crashAnnotationFd); + public static native void nativeRun(String[] args, int prefsFd, int prefMapFd, int ipcFd, int crashFd, int crashAnnotationFd); private static native void loadGeckoLibsNative(String apkName); private static native void loadSQLiteLibsNative(String apkName); private static native void loadNSSLibsNative(String apkName); diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/process/GeckoProcessManager.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/process/GeckoProcessManager.java index d733ea5560e1..ec0d747279ad 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/process/GeckoProcessManager.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/process/GeckoProcessManager.java @@ -182,9 +182,10 @@ public final class GeckoProcessManager extends IProcessManager.Stub { @WrapForJNI private static int start(final String type, final String[] args, - final int prefsFd, final int ipcFd, + final int prefsFd, final int prefMapFd, + final int ipcFd, final int crashFd, final int crashAnnotationFd) { - return INSTANCE.start(type, args, prefsFd, ipcFd, crashFd, crashAnnotationFd, /* retry */ false); + return INSTANCE.start(type, args, prefsFd, prefMapFd, ipcFd, crashFd, crashAnnotationFd, /* retry */ false); } private int filterFlagsForChild(int flags) { @@ -192,7 +193,8 @@ public final class GeckoProcessManager extends IProcessManager.Stub { GeckoThread.FLAG_ENABLE_NATIVE_CRASHREPORTER); } - private int start(final String type, final String[] args, final int prefsFd, + private int start(final String type, final String[] args, + final int prefsFd, final int prefMapFd, final int ipcFd, final int crashFd, final int crashAnnotationFd, final boolean retry) { final ChildConnection connection = getConnection(type); @@ -203,11 +205,13 @@ public final class GeckoProcessManager extends IProcessManager.Stub { final Bundle extras = GeckoThread.getActiveExtras(); final ParcelFileDescriptor prefsPfd; + final ParcelFileDescriptor prefMapPfd; final ParcelFileDescriptor ipcPfd; final ParcelFileDescriptor crashPfd; final ParcelFileDescriptor crashAnnotationPfd; try { prefsPfd = ParcelFileDescriptor.fromFd(prefsFd); + prefMapPfd = ParcelFileDescriptor.fromFd(prefMapFd); ipcPfd = ParcelFileDescriptor.fromFd(ipcFd); crashPfd = (crashFd >= 0) ? ParcelFileDescriptor.fromFd(crashFd) : null; crashAnnotationPfd = (crashAnnotationFd >= 0) ? ParcelFileDescriptor.fromFd(crashAnnotationFd) : null; @@ -220,8 +224,8 @@ public final class GeckoProcessManager extends IProcessManager.Stub { boolean started = false; try { - started = child.start(this, args, extras, flags, prefsPfd, ipcPfd, crashPfd, - crashAnnotationPfd); + started = child.start(this, args, extras, flags, prefsPfd, prefMapPfd, + ipcPfd, crashPfd, crashAnnotationPfd); } catch (final RemoteException e) { } @@ -232,7 +236,7 @@ public final class GeckoProcessManager extends IProcessManager.Stub { } Log.w(LOGTAG, "Attempting to kill running child " + type); connection.unbind(); - return start(type, args, prefsFd, ipcFd, crashFd, crashAnnotationFd, /* retry */ true); + return start(type, args, prefsFd, prefMapFd, ipcFd, crashFd, crashAnnotationFd, /* retry */ true); } try { diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/process/GeckoServiceChildProcess.java b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/process/GeckoServiceChildProcess.java index f328388a4f7e..9335fb611553 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/process/GeckoServiceChildProcess.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/process/GeckoServiceChildProcess.java @@ -62,6 +62,7 @@ public class GeckoServiceChildProcess extends Service { final Bundle extras, final int flags, final ParcelFileDescriptor prefsPfd, + final ParcelFileDescriptor prefMapPfd, final ParcelFileDescriptor ipcPfd, final ParcelFileDescriptor crashReporterPfd, final ParcelFileDescriptor crashAnnotationPfd) { @@ -74,6 +75,7 @@ public class GeckoServiceChildProcess extends Service { } final int prefsFd = prefsPfd.detachFd(); + final int prefMapFd = prefMapPfd.detachFd(); final int ipcFd = ipcPfd.detachFd(); final int crashReporterFd = crashReporterPfd != null ? crashReporterPfd.detachFd() : -1; @@ -83,8 +85,8 @@ public class GeckoServiceChildProcess extends Service { ThreadUtils.postToUiThread(new Runnable() { @Override public void run() { - if (GeckoThread.initChildProcess(args, extras, flags, prefsFd, ipcFd, crashReporterFd, - crashAnnotationFd)) { + if (GeckoThread.initChildProcess(args, extras, flags, prefsFd, prefMapFd, ipcFd, + crashReporterFd, crashAnnotationFd)) { GeckoThread.launch(); } } diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoResult.java b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoResult.java index 529ae1965535..5de1e1782db5 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoResult.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoResult.java @@ -2,6 +2,7 @@ package org.mozilla.geckoview; import org.mozilla.gecko.util.ThreadUtils; +import android.os.Handler; import android.os.Looper; import android.support.annotation.NonNull; import android.support.annotation.Nullable; @@ -148,6 +149,7 @@ public class GeckoResult { } } + private Handler mHandler; private boolean mComplete; private T mValue; private Throwable mError; @@ -159,18 +161,21 @@ public class GeckoResult { * {@link #completeExceptionally(Throwable)} in order to fulfill the result. */ public GeckoResult() { + if (ThreadUtils.isOnUiThread()) { + mHandler = ThreadUtils.getUiHandler(); + } else { + mHandler = new Handler(); + } } /** - * Construct a result from another result. Listeners are not copied. + * This constructs a result that is chained to the specified result. * - * @param from The {@link GeckoResult} to copy. + * @param from The {@link GeckoResult} to copy. */ public GeckoResult(GeckoResult from) { this(); - mComplete = from.mComplete; - mValue = from.mValue; - mError = from.mError; + completeFrom(from); } /** @@ -252,8 +257,10 @@ public class GeckoResult { /** * Adds listeners to be called when the {@link GeckoResult} is completed either with - * a value or {@link Throwable}. Listeners will be invoked on the main thread. If the - * result is already complete when this method is called, listeners will be invoked in + * a value or {@link Throwable}. Listeners will be invoked on the thread where the + * {@link GeckoResult} was created, which must have a {@link Looper} installed. + * + * If the result is already complete when this method is called, listeners will be invoked in * a future {@link Looper} iteration. * * @param valueListener An instance of {@link OnValueListener}, called when the @@ -317,7 +324,7 @@ public class GeckoResult { return; } - ThreadUtils.getUiHandler().post(new Runnable() { + mHandler.post(new Runnable() { @Override public void run() { if (mListeners != null) { @@ -338,7 +345,7 @@ public class GeckoResult { throw new IllegalStateException("Cannot dispatch unless result is complete"); } - ThreadUtils.getUiHandler().post(new Runnable() { + mHandler.post(new Runnable() { @Override public void run() { runnable.run(); diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java index 86791b28d67a..505e6eda3fed 100644 --- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java +++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/GeckoSession.java @@ -202,36 +202,65 @@ public class GeckoSession extends LayerSession final int where = convertGeckoTarget(message.getInt("where")); final int flags = filterFlags(message.getInt("flags")); - delegate.onLoadRequest(GeckoSession.this, uri, where, flags, - new GeckoResponse() { - @Override - public void respond(Boolean handled) { - callback.sendSuccess(handled); - } - }); + final GeckoResult result = delegate.onLoadRequest(GeckoSession.this, + uri, where, flags); + + if (result == null) { + callback.sendSuccess(null); + return; + } + + result.then(new GeckoResult.OnValueListener() { + @Override + public GeckoResult onValue(Boolean value) throws Throwable { + ThreadUtils.assertOnUiThread(); + callback.sendSuccess(value); + return null; + } + }, new GeckoResult.OnExceptionListener() { + @Override + public GeckoResult onException(Throwable exception) throws Throwable { + callback.sendError(exception.getMessage()); + return null; + } + }); } else if ("GeckoView:OnNewSession".equals(event)) { final String uri = message.getString("uri"); - delegate.onNewSession(GeckoSession.this, uri, - new GeckoResponse() { - @Override - public void respond(GeckoSession session) { - if (session == null) { - callback.sendSuccess(null); - return; - } + final GeckoResult result = delegate.onNewSession(GeckoSession.this, uri); + if (result == null) { + callback.sendSuccess(null); + return; + } - if (session.isOpen()) { - throw new IllegalArgumentException("Must use an unopened GeckoSession instance"); - } - - if (GeckoSession.this.mWindow == null) { - callback.sendError("Session is not attached to a window"); - } else { - session.open(GeckoSession.this.mWindow.runtime); - callback.sendSuccess(session.getId()); - } + result.then(new GeckoResult.OnValueListener() { + @Override + public GeckoResult onValue(GeckoSession session) throws Throwable { + ThreadUtils.assertOnUiThread(); + if (session == null) { + callback.sendSuccess(null); + return null; } - }); + + if (session.isOpen()) { + throw new IllegalArgumentException("Must use an unopened GeckoSession instance"); + } + + if (GeckoSession.this.mWindow == null) { + callback.sendError("Session is not attached to a window"); + } else { + session.open(GeckoSession.this.mWindow.runtime); + callback.sendSuccess(session.getId()); + } + + return null; + } + }, new GeckoResult.OnExceptionListener() { + @Override + public GeckoResult onException(Throwable exception) throws Throwable { + callback.sendError(exception.getMessage()); + return null; + } + }); } } }; @@ -2223,14 +2252,16 @@ public class GeckoSession extends LayerSession * @param flags The load request flags. * One or more of {@link #LOAD_REQUEST_IS_USER_TRIGGERED * LOAD_REQUEST_*}. - * @param response A response which will state whether or not the load - * was handled. If unhandled, Gecko will continue the - * load as normal. + * + * @return A {@link GeckoResult} with a boolean value which indicates whether or + * not the load was handled. If unhandled, Gecko will continue the + * load as normal. If handled (true value), Gecko will abandon the load. + * A null return value is interpreted as false (unhandled). */ - void onLoadRequest(GeckoSession session, String uri, - @TargetWindow int target, - @LoadRequestFlags int flags, - GeckoResponse response); + @Nullable GeckoResult onLoadRequest(@NonNull GeckoSession session, + @NonNull String uri, + @TargetWindow int target, + @LoadRequestFlags int flags); /** * A request has been made to open a new session. The URI is provided only for @@ -2240,9 +2271,11 @@ public class GeckoSession extends LayerSession * @param session The GeckoSession that initiated the callback. * @param uri The URI to be loaded. * - * @param response A Response which will hold the returned GeckoSession + * @return A {@link GeckoResult} which holds the returned GeckoSession. May be null, in + * which case the request for a new window by web content will fail. e.g., + * window.open() will return null. */ - void onNewSession(GeckoSession session, String uri, GeckoResponse response); + @Nullable GeckoResult onNewSession(@NonNull GeckoSession session, @NonNull String uri); } /** diff --git a/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java b/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java index 3b428287f73c..3947d1af3d67 100644 --- a/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java +++ b/mobile/android/geckoview_example/src/main/java/org/mozilla/geckoview_example/GeckoViewActivity.java @@ -7,6 +7,7 @@ package org.mozilla.geckoview_example; import org.mozilla.geckoview.BasicSelectionActionDelegate; import org.mozilla.geckoview.GeckoResponse; +import org.mozilla.geckoview.GeckoResult; import org.mozilla.geckoview.GeckoRuntime; import org.mozilla.geckoview.GeckoRuntimeSettings; import org.mozilla.geckoview.GeckoSession; @@ -561,18 +562,16 @@ public class GeckoViewActivity extends AppCompatActivity { } @Override - public void onLoadRequest(final GeckoSession session, final String uri, - final int target, final int flags, - GeckoResponse response) { + public GeckoResult onLoadRequest(final GeckoSession session, final String uri, + final int target, final int flags) { Log.d(LOGTAG, "onLoadRequest=" + uri + " where=" + target + " flags=" + flags); - response.respond(false); + return GeckoResult.fromValue(false); } @Override - public void onNewSession(final GeckoSession session, final String uri, GeckoResponse response) { + public GeckoResult onNewSession(final GeckoSession session, final String uri) { GeckoSession newSession = new GeckoSession(session.getSettings()); - response.respond(newSession); Intent intent = new Intent(GeckoViewActivity.this, SessionActivity.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); @@ -581,6 +580,8 @@ public class GeckoViewActivity extends AppCompatActivity { intent.putExtra("session", newSession); startActivity(intent); + + return GeckoResult.fromValue(newSession); } } diff --git a/mobile/android/modules/geckoview/GeckoViewContent.jsm b/mobile/android/modules/geckoview/GeckoViewContent.jsm index 4135a7aa696a..228793c65201 100644 --- a/mobile/android/modules/geckoview/GeckoViewContent.jsm +++ b/mobile/android/modules/geckoview/GeckoViewContent.jsm @@ -139,7 +139,13 @@ class GeckoViewContent extends GeckoViewModule { warn `Failed to save state due to missing callback`; return; } - this._saveStateCallbacks.get(aMsg.data.id).onSuccess(aMsg.data.state); + + const callback = this._saveStateCallbacks.get(aMsg.data.id); + if (aMsg.data.error) { + callback.onError(aMsg.data.error); + } else { + callback.onSuccess(aMsg.data.state); + } this._saveStateCallbacks.delete(aMsg.data.id); break; } diff --git a/modules/libpref/Preferences.cpp b/modules/libpref/Preferences.cpp index 8af280d5fa5e..e35ebb0894af 100644 --- a/modules/libpref/Preferences.cpp +++ b/modules/libpref/Preferences.cpp @@ -8,6 +8,8 @@ #include #include +#include "SharedPrefMap.h" + #include "base/basictypes.h" #include "GeckoProfiler.h" #include "MainThreadUtils.h" @@ -93,6 +95,8 @@ using namespace mozilla; +using mozilla::ipc::FileDescriptor; + #ifdef DEBUG #define ENSURE_PARENT_PROCESS(func, pref) \ @@ -127,15 +131,6 @@ static const uint32_t MAX_PREF_LENGTH = 1 * 1024 * 1024; // Actually, 4kb should be enough for everyone. static const uint32_t MAX_ADVISABLE_PREF_LENGTH = 4 * 1024; -// Keep this in sync with PrefType in parser/src/lib.rs. -enum class PrefType : uint8_t -{ - None = 0, // only used when neither the default nor user value is set - String = 1, - Int = 2, - Bool = 3, -}; - // This is used for pref names and string pref values. We encode the string // length, then a '/', then the string chars. This encoding means there are no // special chars that are forbidden or require escaping. @@ -165,6 +160,23 @@ union PrefValue { int32_t mIntVal; bool mBoolVal; + PrefValue() = default; + + explicit PrefValue(bool aVal) + : mBoolVal(aVal) + { + } + + explicit PrefValue(int32_t aVal) + : mIntVal(aVal) + { + } + + explicit PrefValue(const char* aVal) + : mStringVal(aVal) + { + } + bool Equals(PrefType aType, PrefValue aValue) { switch (aType) { @@ -189,6 +201,9 @@ union PrefValue { } } + template + T Get() const; + void Init(PrefType aNewType, PrefValue aNewValue) { if (aNewType == PrefType::String) { @@ -318,6 +333,27 @@ union PrefValue { } }; +template<> +bool +PrefValue::Get() const +{ + return mBoolVal; +} + +template<> +int32_t +PrefValue::Get() const +{ + return mIntVal; +} + +template<> +nsDependentCString +PrefValue::Get() const +{ + return nsDependentCString(mStringVal); +} + #ifdef DEBUG const char* PrefTypeToString(PrefType aType) @@ -416,7 +452,11 @@ struct PrefsSizes }; } -static ArenaAllocator<8192, 1> gPrefNameArena; +static StaticRefPtr gSharedMap; + +static ArenaAllocator<4096, 1> gPrefNameArena; + +class PrefWrapper; class Pref { @@ -428,7 +468,6 @@ public: , mIsLocked(false) , mHasDefaultValue(false) , mHasUserValue(false) - , mHasChangedSinceInit(false) , mDefaultValue() , mUserValue() { @@ -443,7 +482,8 @@ public: mUserValue.Clear(Type()); } - const char* Name() { return mName; } + const char* Name() const { return mName; } + nsDependentCString NameString() const { return nsDependentCString(mName); } // Types. @@ -459,39 +499,33 @@ public: // Other properties. bool IsLocked() const { return mIsLocked; } - void SetIsLocked(bool aValue) - { - mIsLocked = aValue; - mHasChangedSinceInit = true; - } + void SetIsLocked(bool aValue) { mIsLocked = aValue; } + + bool IsSticky() const { return mIsSticky; } bool HasDefaultValue() const { return mHasDefaultValue; } bool HasUserValue() const { return mHasUserValue; } - // When a content process is created we could tell it about every pref. But - // the content process also initializes prefs from file, so we save a lot of - // IPC if we only tell it about prefs that have changed since initialization. - // - // Specifically, we send a pref if any of the following conditions are met. - // - // - If the pref has changed in any way (default value, user value, or other - // attribute, such as whether it is locked) since being initialized from - // file. - // - // - If the pref has a user value. (User values are more complicated than - // default values, because they can be loaded from file after - // initialization with Preferences::ReadUserPrefsFromFile(), so we are - // conservative with them.) - // - // In other words, prefs that only have a default value and haven't changed - // need not be sent. One could do better with effort, but it's ok to be - // conservative and this still greatly reduces the number of prefs sent. - // - // Note: This function is only useful in the parent process. - bool MustSendToContentProcesses() const + template + void AddToMap(SharedPrefMapBuilder& aMap) { - MOZ_ASSERT(XRE_IsParentProcess()); - return mHasUserValue || mHasChangedSinceInit; + aMap.Add(Name(), + { HasDefaultValue(), HasUserValue(), IsSticky(), IsLocked() }, + HasDefaultValue() ? mDefaultValue.Get() : T(), + HasUserValue() ? mUserValue.Get() : T()); + } + + void AddToMap(SharedPrefMapBuilder& aMap) + { + if (IsTypeBool()) { + AddToMap(aMap); + } else if (IsTypeInt()) { + AddToMap(aMap); + } else if (IsTypeString()) { + AddToMap(aMap); + } else { + MOZ_ASSERT_UNREACHABLE("Unexpected preference type"); + } } // Other operations. @@ -505,63 +539,41 @@ public: return strcmp(mName, aPrefName) == 0; } - nsresult GetBoolValue(PrefValueKind aKind, bool* aResult) + bool GetBoolValue(PrefValueKind aKind = PrefValueKind::User) const { - if (!IsTypeBool()) { - return NS_ERROR_UNEXPECTED; - } + MOZ_ASSERT(IsTypeBool()); + MOZ_ASSERT(aKind == PrefValueKind::Default ? HasDefaultValue() + : HasUserValue()); - if (aKind == PrefValueKind::Default || IsLocked() || !mHasUserValue) { - // Do we have a default? - if (!mHasDefaultValue) { - return NS_ERROR_UNEXPECTED; - } - *aResult = mDefaultValue.mBoolVal; - } else { - *aResult = mUserValue.mBoolVal; - } - - return NS_OK; + return aKind == PrefValueKind::Default ? mDefaultValue.mBoolVal + : mUserValue.mBoolVal; } - nsresult GetIntValue(PrefValueKind aKind, int32_t* aResult) + int32_t GetIntValue(PrefValueKind aKind = PrefValueKind::User) const { - if (!IsTypeInt()) { - return NS_ERROR_UNEXPECTED; - } + MOZ_ASSERT(IsTypeInt()); + MOZ_ASSERT(aKind == PrefValueKind::Default ? HasDefaultValue() + : HasUserValue()); - if (aKind == PrefValueKind::Default || IsLocked() || !mHasUserValue) { - // Do we have a default? - if (!mHasDefaultValue) { - return NS_ERROR_UNEXPECTED; - } - *aResult = mDefaultValue.mIntVal; - } else { - *aResult = mUserValue.mIntVal; - } - - return NS_OK; + return aKind == PrefValueKind::Default ? mDefaultValue.mIntVal + : mUserValue.mIntVal; } - nsresult GetCStringValue(PrefValueKind aKind, nsACString& aResult) + const char* GetBareStringValue( + PrefValueKind aKind = PrefValueKind::User) const { - if (!IsTypeString()) { - return NS_ERROR_UNEXPECTED; - } + MOZ_ASSERT(IsTypeString()); + MOZ_ASSERT(aKind == PrefValueKind::Default ? HasDefaultValue() + : HasUserValue()); - if (aKind == PrefValueKind::Default || IsLocked() || !mHasUserValue) { - // Do we have a default? - if (!mHasDefaultValue) { - return NS_ERROR_UNEXPECTED; - } - MOZ_ASSERT(mDefaultValue.mStringVal); - aResult = mDefaultValue.mStringVal; - } else { - MOZ_ASSERT(mUserValue.mStringVal); - aResult = mUserValue.mStringVal; - } + return aKind == PrefValueKind::Default ? mDefaultValue.mStringVal + : mUserValue.mStringVal; + } - return NS_OK; + nsDependentCString GetStringValue( + PrefValueKind aKind = PrefValueKind::User) const + { + return nsDependentCString(GetBareStringValue(aKind)); } void ToDomPref(dom::Pref* aDomPref) @@ -633,13 +645,13 @@ public: userValueChanged = true; } - mHasChangedSinceInit = true; - if (userValueChanged || (defaultValueChanged && !mHasUserValue)) { *aValueChanged = true; } } + void FromWrapper(PrefWrapper& aWrapper); + bool HasAdvisablySizedValues() { MOZ_ASSERT(XRE_IsParentProcess()); @@ -680,14 +692,12 @@ public: { mUserValue.Clear(Type()); mHasUserValue = false; - mHasChangedSinceInit = true; } nsresult SetDefaultValue(PrefType aType, PrefValue aValue, bool aIsSticky, bool aIsLocked, - bool aFromInit, bool* aValueChanged) { // Types must always match when setting the default value. @@ -704,9 +714,6 @@ public: if (!ValueMatches(PrefValueKind::Default, aType, aValue)) { mDefaultValue.Replace(mHasDefaultValue, Type(), aType, aValue); mHasDefaultValue = true; - if (!aFromInit) { - mHasChangedSinceInit = true; - } if (aIsSticky) { mIsSticky = true; } @@ -749,9 +756,6 @@ public: mUserValue.Replace(mHasUserValue, Type(), aType, aValue); SetType(aType); // needed because we may have changed the type mHasUserValue = true; - if (!aFromInit) { - mHasChangedSinceInit = true; - } if (!IsLocked()) { *aValueChanged = true; } @@ -759,30 +763,6 @@ public: return NS_OK; } - // Returns false if this pref doesn't have a user value worth saving. - bool UserValueToStringForSaving(nsCString& aStr) - { - // Should we save the user value, if present? Only if it does not match the - // default value, or it is sticky. - if (mHasUserValue && - (!ValueMatches(PrefValueKind::Default, Type(), mUserValue) || - mIsSticky)) { - if (IsTypeString()) { - StrEscape(mUserValue.mStringVal, aStr); - - } else if (IsTypeInt()) { - aStr.AppendInt(mUserValue.mIntVal); - - } else if (IsTypeBool()) { - aStr = mUserValue.mBoolVal ? "true" : "false"; - } - return true; - } - - // Do not save default prefs that haven't changed. - return false; - } - // Prefs are serialized in a manner that mirrors dom::Pref. The two should be // kept in sync. E.g. if something is added to one it should also be added to // the other. (It would be nice to be able to use the code generated from @@ -958,7 +938,6 @@ private: uint32_t mIsLocked : 1; uint32_t mHasDefaultValue : 1; uint32_t mHasUserValue : 1; - uint32_t mHasChangedSinceInit : 1; PrefValue mDefaultValue; PrefValue mUserValue; @@ -967,10 +946,6 @@ private: class PrefEntry : public PLDHashEntryHdr { public: -#ifdef DEBUG - // This field is before mPref to minimize sizeof(PrefEntry) on 64-bit. - uint32_t mAccessCount; -#endif Pref* mPref; // Note: this is never null in a live entry. static bool MatchEntry(const PLDHashEntryHdr* aEntry, const void* aKey) @@ -986,9 +961,6 @@ public: auto entry = static_cast(aEntry); auto prefName = static_cast(aKey); -#ifdef DEBUG - entry->mAccessCount = 0; -#endif entry->mPref = new Pref(prefName); } @@ -1001,6 +973,211 @@ public: } }; +using PrefWrapperBase = Variant; +class MOZ_STACK_CLASS PrefWrapper : public PrefWrapperBase +{ + using SharedPref = const SharedPrefMap::Pref; + +public: + MOZ_IMPLICIT PrefWrapper(Pref* aPref) + : PrefWrapperBase(AsVariant(aPref)) + { + } + + MOZ_IMPLICIT PrefWrapper(const SharedPrefMap::Pref& aPref) + : PrefWrapperBase(AsVariant(aPref)) + { + } + + // Types. + + bool IsType(PrefType aType) const { return Type() == aType; } + bool IsTypeNone() const { return IsType(PrefType::None); } + bool IsTypeString() const { return IsType(PrefType::String); } + bool IsTypeInt() const { return IsType(PrefType::Int); } + bool IsTypeBool() const { return IsType(PrefType::Bool); } + +#define FORWARD(retType, method) \ + retType method() const \ + { \ + struct Matcher \ + { \ + retType match(const Pref* aPref) { return aPref->method(); } \ + retType match(SharedPref& aPref) { return aPref.method(); } \ + }; \ + return match(Matcher()); \ + } + + FORWARD(bool, IsLocked) + FORWARD(bool, IsSticky) + FORWARD(bool, HasDefaultValue) + FORWARD(bool, HasUserValue) + FORWARD(const char*, Name) + FORWARD(nsCString, NameString) + FORWARD(PrefType, Type) +#undef FORWARD + +#define FORWARD(retType, method) \ + retType method(PrefValueKind aKind = PrefValueKind::User) const \ + { \ + struct Matcher \ + { \ + PrefValueKind mKind; \ + \ + retType match(const Pref* aPref) { return aPref->method(mKind); } \ + retType match(SharedPref& aPref) { return aPref.method(mKind); } \ + }; \ + return match(Matcher{ aKind }); \ + } + + FORWARD(bool, GetBoolValue) + FORWARD(int32_t, GetIntValue) + FORWARD(nsCString, GetStringValue) + FORWARD(const char*, GetBareStringValue) +#undef FORWARD + + PrefValue GetValue(PrefValueKind aKind = PrefValueKind::User) const + { + switch (Type()) { + case PrefType::Bool: + return PrefValue{ GetBoolValue(aKind) }; + case PrefType::Int: + return PrefValue{ GetIntValue(aKind) }; + case PrefType::String: + return PrefValue{ GetBareStringValue(aKind) }; + default: + MOZ_ASSERT_UNREACHABLE("Unexpected pref type"); + return PrefValue{}; + } + } + + Result WantValueKind(PrefType aType, + PrefValueKind aKind) const + { + if (Type() != aType) { + return Err(NS_ERROR_UNEXPECTED); + } + + if (aKind == PrefValueKind::Default || IsLocked() || !HasUserValue()) { + if (!HasDefaultValue()) { + return Err(NS_ERROR_UNEXPECTED); + } + return PrefValueKind::Default; + } + return PrefValueKind::User; + } + + nsresult GetBoolValue(PrefValueKind aKind, bool* aResult) const + { + PrefValueKind kind; + MOZ_TRY_VAR(kind, WantValueKind(PrefType::Bool, aKind)); + + *aResult = GetBoolValue(kind); + return NS_OK; + } + + nsresult GetIntValue(PrefValueKind aKind, int32_t* aResult) const + { + PrefValueKind kind; + MOZ_TRY_VAR(kind, WantValueKind(PrefType::Int, aKind)); + + *aResult = GetIntValue(kind); + return NS_OK; + } + + nsresult GetCStringValue(PrefValueKind aKind, nsACString& aResult) const + { + PrefValueKind kind; + MOZ_TRY_VAR(kind, WantValueKind(PrefType::String, aKind)); + + aResult = GetStringValue(kind); + return NS_OK; + } + + // Returns false if this pref doesn't have a user value worth saving. + bool UserValueToStringForSaving(nsCString& aStr) + { + // Should we save the user value, if present? Only if it does not match the + // default value, or it is sticky. + if (HasUserValue() && + (!ValueMatches(PrefValueKind::Default, Type(), GetValue()) || + IsSticky())) { + if (IsTypeString()) { + StrEscape(GetStringValue().get(), aStr); + + } else if (IsTypeInt()) { + aStr.AppendInt(GetIntValue()); + + } else if (IsTypeBool()) { + aStr = GetBoolValue() ? "true" : "false"; + } + return true; + } + + // Do not save default prefs that haven't changed. + return false; + } + + bool Matches(PrefType aType, + PrefValueKind aKind, + PrefValue& aValue, + bool aIsSticky, + bool aIsLocked) const + { + return (ValueMatches(aKind, aType, aValue) && aIsSticky == IsSticky() && + aIsLocked == IsLocked()); + } + + bool ValueMatches(PrefValueKind aKind, + PrefType aType, + const PrefValue& aValue) const + { + if (!IsType(aType)) { + return false; + } + if (!(aKind == PrefValueKind::Default ? HasDefaultValue() + : HasUserValue())) { + return false; + } + switch (aType) { + case PrefType::Bool: + return GetBoolValue(aKind) == aValue.mBoolVal; + case PrefType::Int: + return GetIntValue(aKind) == aValue.mIntVal; + case PrefType::String: + return strcmp(GetBareStringValue(aKind), aValue.mStringVal) == 0; + default: + MOZ_ASSERT_UNREACHABLE("Unexpected preference type"); + return false; + } + } +}; + +void +Pref::FromWrapper(PrefWrapper& aWrapper) +{ + MOZ_ASSERT(aWrapper.is()); + auto pref = aWrapper.as(); + + MOZ_ASSERT(IsTypeNone()); + MOZ_ASSERT(strcmp(mName, pref.Name()) == 0); + + mType = uint32_t(pref.Type()); + + mIsLocked = pref.IsLocked(); + mIsSticky = pref.IsSticky(); + + mHasDefaultValue = pref.HasDefaultValue(); + mHasUserValue = pref.HasUserValue(); + + if (mHasDefaultValue) { + mDefaultValue.Init(Type(), aWrapper.GetValue(PrefValueKind::Default)); + } + if (mHasUserValue) { + mUserValue.Init(Type(), aWrapper.GetValue(PrefValueKind::User)); + } +} + class CallbackNode { public: @@ -1076,6 +1253,43 @@ static PLDHashTable* gHashTable; static CallbackNode* gFirstCallback = nullptr; static CallbackNode* gLastPriorityNode = nullptr; +#ifdef DEBUG +#define ACCESS_COUNTS +#endif + +#ifdef ACCESS_COUNTS +using AccessCountsHashTable = nsDataHashtable; +static AccessCountsHashTable* gAccessCounts; + +static void +AddAccessCount(const nsACString& aPrefName) +{ + // FIXME: Servo reads preferences from background threads in unsafe ways (bug + // 1474789), and triggers assertions here if we try to add usage count entries + // from background threads. + if (NS_IsMainThread()) { + uint32_t& count = gAccessCounts->GetOrInsert(aPrefName); + count++; + } +} + +static void +AddAccessCount(const char* aPrefName) +{ + AddAccessCount(nsDependentCString(aPrefName)); +} +#else +static void MOZ_MAYBE_UNUSED +AddAccessCount(const nsACString& aPrefName) +{ +} + +static void +AddAccessCount(const char* aPrefName) +{ +} +#endif + // These are only used during the call to NotifyCallbacks(). static bool gCallbacksInProgress = false; static bool gShouldCleanupDeadNodes = false; @@ -1086,13 +1300,266 @@ static PLDHashTableOps pref_HashTableOps = { PrefEntry::InitEntry, }; +class PrefsHashIter +{ + using Iterator = decltype(gHashTable->Iter()); + using ElemType = Pref*; + + Iterator mIter; + +public: + explicit PrefsHashIter(PLDHashTable* aTable) + : mIter(aTable->Iter()) + { + } + + class Elem + { + friend class PrefsHashIter; + + PrefsHashIter& mParent; + bool mDone; + + Elem(PrefsHashIter& aIter, bool aDone) + : mParent(aIter) + , mDone(aDone) + { + } + + Iterator& Iter() { return mParent.mIter; } + + public: + Elem& operator*() { return *this; } + + ElemType get() + { + if (mDone) { + return nullptr; + } + return static_cast(Iter().Get())->mPref; + } + ElemType get() const { return const_cast(this)->get(); } + + ElemType operator->() { return get(); } + ElemType operator->() const { return get(); } + + operator ElemType() { return get(); } + + void Remove() { Iter().Remove(); } + + Elem& operator++() + { + MOZ_ASSERT(!mDone); + Iter().Next(); + mDone = Iter().Done(); + return *this; + } + + bool operator!=(Elem& other) + { + return mDone != other.mDone || this->get() != other.get(); + } + }; + + Elem begin() { return Elem(*this, mIter.Done()); } + + Elem end() { return Elem(*this, true); } +}; + +class PrefsIter +{ + using Iterator = decltype(gHashTable->Iter()); + using ElemType = PrefWrapper; + + using HashElem = PrefsHashIter::Elem; + using SharedElem = SharedPrefMap::Pref; + + using ElemTypeVariant = Variant; + + SharedPrefMap* mSharedMap; + PLDHashTable* mHashTable; + PrefsHashIter mIter; + + ElemTypeVariant mPos; + ElemTypeVariant mEnd; + + Maybe mEntry; + +public: + PrefsIter(PLDHashTable* aHashTable, SharedPrefMap* aSharedMap) + : mSharedMap(aSharedMap) + , mHashTable(aHashTable) + , mIter(aHashTable) + , mPos(AsVariant(mIter.begin())) + , mEnd(AsVariant(mIter.end())) + { + if (Done()) { + NextIterator(); + } + } + +private: +#define MATCH(type, ...) \ + do { \ + struct Matcher \ + { \ + PrefsIter& mIter; \ + type match(HashElem& pos) \ + { \ + HashElem& end MOZ_MAYBE_UNUSED = mIter.mEnd.as(); \ + __VA_ARGS__; \ + } \ + type match(SharedElem& pos) \ + { \ + SharedElem& end MOZ_MAYBE_UNUSED = mIter.mEnd.as(); \ + __VA_ARGS__; \ + } \ + }; \ + return mPos.match(Matcher{ *this }); \ + } while (0); + + bool Done() { MATCH(bool, return pos == end); } + + PrefWrapper MakeEntry() { MATCH(PrefWrapper, return PrefWrapper(pos)); } + + void NextEntry() + { + mEntry.reset(); + MATCH(void, ++pos); + } +#undef MATCH + + bool Next() + { + NextEntry(); + return !Done() || NextIterator(); + } + + bool NextIterator() + { + if (mPos.is() && mSharedMap) { + mPos = AsVariant(mSharedMap->begin()); + mEnd = AsVariant(mSharedMap->end()); + return !Done(); + } + return false; + } + + bool IteratingBase() { return mPos.is(); } + + PrefWrapper& Entry() + { + MOZ_ASSERT(!Done()); + + if (!mEntry.isSome()) { + mEntry.emplace(MakeEntry()); + } + return mEntry.ref(); + } + +public: + class Elem + { + friend class PrefsIter; + + PrefsIter& mParent; + bool mDone; + + Elem(PrefsIter& aIter, bool aDone) + : mParent(aIter) + , mDone(aDone) + { + SkipDuplicates(); + } + + void Next() { mDone = !mParent.Next(); } + + void SkipDuplicates() + { + while (!mDone && (mParent.IteratingBase() + ? !!mParent.mHashTable->Search(ref().Name()) + : ref().IsTypeNone())) { + Next(); + } + } + + public: + Elem& operator*() { return *this; } + + ElemType& ref() { return mParent.Entry(); } + const ElemType& ref() const { return const_cast(this)->ref(); } + + ElemType* operator->() { return &ref(); } + const ElemType* operator->() const { return &ref(); } + + operator ElemType() { return ref(); } + + void Remove() + { + MOZ_ASSERT(!mParent.IteratingBase()); + mParent.mPos.as().Remove(); + } + + Elem& operator++() + { + MOZ_ASSERT(!mDone); + Next(); + SkipDuplicates(); + return *this; + } + + bool operator!=(Elem& other) + { + if (mDone != other.mDone) { + return true; + } + if (mDone) { + return false; + } + return &this->ref() != &other.ref(); + } + }; + + Elem begin() { return { *this, Done() }; } + + Elem end() { return { *this, true }; } +}; + static Pref* pref_HashTableLookup(const char* aPrefName); static void -NotifyCallbacks(const char* aPrefName); +NotifyCallbacks(const char* aPrefName, const PrefWrapper* aPref = nullptr); -#define PREF_HASHTABLE_INITIAL_LENGTH 1024 +static void +NotifyCallbacks(const char* aPrefName, const PrefWrapper& aPref) +{ + NotifyCallbacks(aPrefName, &aPref); +} + +// The approximate number of preferences in the dynamic hashtable for the parent +// and content processes, respectively. These numbers are used to determine the +// initial size of the dynamic preference hashtables, and should be chosen to +// avoid rehashing during normal usage. The actual number of preferences will, +// or course, change over time, but these numbers only need to be within a +// binary order of magnitude of the actual values to remain effective. +// +// The number for the parent process should reflect the total number of +// preferences in the database, since the parent process needs to initially +// build a dynamic hashtable of the entire preference database. The number for +// the child process should reflect the number of preferences which are likely +// to change after the startup of the first content process, since content +// processes only store changed preferences on top of a snapshot of the database +// created at startup. +// +// Note: The capacity of a hashtable doubles when its length reaches an exact +// power of two. A table with an initial length of 64 is twice as large as one +// with an initial length of 63. This is important in content processes, where +// lookup speed is less critical and we pay the price of the additional overhead +// for each content process. So the initial content length should generally be +// *under* the next power-of-two larger than its expected length. +constexpr size_t kHashTableInitialLengthParent = 3000; +constexpr size_t kHashTableInitialLengthContent = 64; static PrefSaveData pref_savePrefs() @@ -1101,9 +1568,7 @@ pref_savePrefs() PrefSaveData savedPrefs(gHashTable->EntryCount()); - for (auto iter = gHashTable->Iter(); !iter.Done(); iter.Next()) { - Pref* pref = static_cast(iter.Get())->mPref; - + for (auto& pref : PrefsIter(gHashTable, gSharedMap)) { nsAutoCString prefValueStr; if (!pref->UserValueToStringForSaving(prefValueStr)) { continue; @@ -1147,13 +1612,65 @@ pref_HashTableLookup(const char* aPrefName) return nullptr; } -#ifdef DEBUG - entry->mAccessCount += 1; -#endif - return entry->mPref; } +// While notifying preference callbacks, this holds the wrapper for the +// preference being notified, in order to optimize lookups. +// +// Note: Callbacks and lookups only happen on the main thread, so this is safe +// to use without locking. +static const PrefWrapper* gCallbackPref; + +Maybe +pref_Lookup(const char* aPrefName, bool aIncludeTypeNone = false) +{ + Maybe result; + + MOZ_ASSERT(NS_IsMainThread() || mozilla::ServoStyleSet::IsInServoTraversal()); + + AddAccessCount(aPrefName); + + if (gCallbackPref && strcmp(aPrefName, gCallbackPref->Name()) == 0) { + result.emplace(*gCallbackPref); + } else if (Pref* pref = pref_HashTableLookup(aPrefName)) { + if (aIncludeTypeNone || !pref->IsTypeNone()) { + result.emplace(pref); + } + } else if (gSharedMap) { + Maybe pref = gSharedMap->Get(aPrefName); + if (pref.isSome()) { + result.emplace(*pref); + } + } + + return result; +} + +static Result +pref_LookupForModify(const char* aPrefName, + const std::function& aCheckFn) +{ + Maybe wrapper = pref_Lookup(aPrefName, /* includeTypeNone */ true); + if (wrapper.isNothing()) { + return Err(NS_ERROR_INVALID_ARG); + } + if (!aCheckFn(*wrapper)) { + return nullptr; + } + if (wrapper->is()) { + return wrapper->as(); + } + + auto entry = static_cast(gHashTable->Add(aPrefName, fallible)); + if (!entry) { + return Err(NS_ERROR_OUT_OF_MEMORY); + } + Pref* pref = entry->mPref; + pref->FromWrapper(*wrapper); + return pref; +} + static nsresult pref_SetPref(const char* aPrefName, PrefType aType, @@ -1169,22 +1686,36 @@ pref_SetPref(const char* aPrefName, return NS_ERROR_OUT_OF_MEMORY; } - auto entry = static_cast(gHashTable->Add(aPrefName, fallible)); - if (!entry) { - return NS_ERROR_OUT_OF_MEMORY; + Pref* pref = nullptr; + if (gSharedMap) { + auto result = + pref_LookupForModify(aPrefName, [&](const PrefWrapper& aWrapper) { + return !aWrapper.Matches(aType, aKind, aValue, aIsSticky, aIsLocked); + }); + if (result.isOk() && !(pref = result.unwrap())) { + // No changes required. + return NS_OK; + } } - Pref* pref = entry->mPref; - if (pref->IsTypeNone()) { - // New entry. Set the type. - pref->SetType(aType); + if (!pref) { + auto entry = static_cast(gHashTable->Add(aPrefName, fallible)); + if (!entry) { + return NS_ERROR_OUT_OF_MEMORY; + } + pref = entry->mPref; + + if (pref->IsTypeNone()) { + // New entry. Set the type. + pref->SetType(aType); + } } bool valueChanged = false; nsresult rv; if (aKind == PrefValueKind::Default) { rv = pref->SetDefaultValue( - aType, aValue, aIsSticky, aIsLocked, aFromInit, &valueChanged); + aType, aValue, aIsSticky, aIsLocked, &valueChanged); } else { MOZ_ASSERT(!aIsLocked); // `locked` is disallowed in user pref files rv = pref->SetUserValue(aType, aValue, aFromInit, &valueChanged); @@ -1206,7 +1737,7 @@ pref_SetPref(const char* aPrefName, if (aKind == PrefValueKind::User && XRE_IsParentProcess()) { Preferences::HandleDirty(); } - NotifyCallbacks(aPrefName); + NotifyCallbacks(aPrefName, PrefWrapper(pref)); } return NS_OK; @@ -1234,10 +1765,13 @@ pref_RemoveCallbackNode(CallbackNode* aNode, CallbackNode* aPrevNode) } static void -NotifyCallbacks(const char* aPrefName) +NotifyCallbacks(const char* aPrefName, const PrefWrapper* aPref) { bool reentered = gCallbacksInProgress; + gCallbackPref = aPref; + auto cleanup = MakeScopeExit([]() { gCallbackPref = nullptr; }); + // Nodes must not be deleted while gCallbacksInProgress is true. // Nodes that need to be deleted are marked for deletion by nulling // out the |func| pointer. We release them at the end of this function @@ -2353,10 +2887,9 @@ nsPrefBranch::GetChildList(const char* aStartingAt, const PrefName& parent = GetPrefName(aStartingAt); size_t parentLen = parent.Length(); - for (auto iter = gHashTable->Iter(); !iter.Done(); iter.Next()) { - Pref* pref = static_cast(iter.Get())->mPref; + for (auto& pref : PrefsIter(gHashTable, gSharedMap)) { if (strncmp(pref->Name(), parent.get(), parentLen) == 0) { - prefArray.AppendElement(pref->Name()); + prefArray.AppendElement(pref->NameString()); } } @@ -2990,6 +3523,10 @@ PreferenceServiceReporter::CollectReports( node->AddSizeOfIncludingThis(mallocSizeOf, sizes); } + if (gSharedMap) { + sizes.mMisc += mallocSizeOf(gSharedMap); + } + MOZ_COLLECT_REPORT("explicit/preferences/hash-table", KIND_HEAP, UNITS_BYTES, @@ -3045,6 +3582,17 @@ PreferenceServiceReporter::CollectReports( sizes.mMisc, "Miscellaneous memory used by libpref."); + if (gSharedMap) { + if (XRE_IsParentProcess()) { + MOZ_COLLECT_REPORT("explicit/preferences/shared-memory-map", + KIND_NONHEAP, + UNITS_BYTES, + gSharedMap->MapSize(), + "The shared memory mapping used to share a " + "snapshot of preference values across processes."); + } + } + nsPrefBranch* rootBranch = static_cast(Preferences::GetRootBranch()); if (!rootBranch) { @@ -3269,12 +3817,20 @@ Preferences::GetInstanceForService() sPreferences = new Preferences(); MOZ_ASSERT(!gHashTable); - gHashTable = new PLDHashTable( - &pref_HashTableOps, sizeof(PrefEntry), PREF_HASHTABLE_INITIAL_LENGTH); + gHashTable = + new PLDHashTable(&pref_HashTableOps, + sizeof(PrefEntry), + (XRE_IsParentProcess() ? kHashTableInitialLengthParent + : kHashTableInitialLengthContent)); gTelemetryLoadData = new nsDataHashtable(); +#ifdef ACCESS_COUNTS + MOZ_ASSERT(!gAccessCounts); + gAccessCounts = new AccessCountsHashTable(); +#endif + gCacheData = new nsTArray>(); gCacheDataDesc = "set by GetInstanceForService() (1)"; @@ -3408,6 +3964,12 @@ Preferences::~Preferences() delete gTelemetryLoadData; gTelemetryLoadData = nullptr; +#ifdef ACCESS_COUNTS + delete gAccessCounts; +#endif + + gSharedMap = nullptr; + gPrefNameArena.Clear(); } @@ -3426,7 +3988,7 @@ Preferences::SerializePreferences(nsCString& aStr) for (auto iter = gHashTable->Iter(); !iter.Done(); iter.Next()) { Pref* pref = static_cast(iter.Get())->mPref; - if (pref->MustSendToContentProcesses() && pref->HasAdvisablySizedValues()) { + if (!pref->IsTypeNone() && pref->HasAdvisablySizedValues()) { pref->SerializeAndAppend(aStr); } } @@ -3459,6 +4021,48 @@ Preferences::DeserializePreferences(char* aStr, size_t aPrefsLen) #endif } +/* static */ FileDescriptor +Preferences::EnsureSnapshot(size_t* aSize) +{ + MOZ_ASSERT(XRE_IsParentProcess()); + + if (!gSharedMap) { + SharedPrefMapBuilder builder; + + for (auto iter = gHashTable->Iter(); !iter.Done(); iter.Next()) { + Pref* pref = static_cast(iter.Get())->mPref; + + pref->AddToMap(builder); + } + + gSharedMap = new SharedPrefMap(std::move(builder)); + + // Once we've built a snapshot of the database, there's no need to continue + // storing dynamic copies of the preferences it contains. Once we reset the + // hashtable, preference lookups will fall back to the snapshot for any + // preferences not in the dynamic hashtable. + // + // And since the majority of the database is now contained in the snapshot, + // we can initialize the hashtable with the expected number of per-session + // changed preferences, rather than the expected total number of + // preferences. + gHashTable->ClearAndPrepareForLength(kHashTableInitialLengthContent); + gPrefNameArena.Clear(); + } + + *aSize = gSharedMap->MapSize(); + return gSharedMap->CloneFileDescriptor(); +} + +/* static */ void +Preferences::InitSnapshot(const FileDescriptor& aHandle, size_t aSize) +{ + MOZ_ASSERT(!XRE_IsParentProcess()); + MOZ_ASSERT(!gSharedMap); + + gSharedMap = new SharedPrefMap(aHandle, aSize); +} + /* static */ void Preferences::InitializeUserPrefs() { @@ -3557,7 +4161,11 @@ Preferences::ResetPrefs() { ENSURE_PARENT_PROCESS("Preferences::ResetPrefs", "all prefs"); - gHashTable->ClearAndPrepareForLength(PREF_HASHTABLE_INITIAL_LENGTH); + if (gSharedMap) { + return NS_ERROR_NOT_AVAILABLE; + } + + gHashTable->ClearAndPrepareForLength(kHashTableInitialLengthParent); gPrefNameArena.Clear(); return InitInitialObjects(/* isStartup */ false).isOk() ? NS_OK @@ -3671,14 +4279,25 @@ Preferences::SetPreference(const dom::Pref& aDomPref) // needlessly, but that's ok because this case is rare. // if (!pref->HasDefaultValue() && !pref->HasUserValue()) { - gHashTable->RemoveEntry(entry); + // If the preference exists in the shared map, we need to keep the dynamic + // entry around to mask it. + if (gSharedMap->Has(pref->Name())) { + pref->SetType(PrefType::None); + } else { + gHashTable->RemoveEntry(entry); + } + pref = nullptr; } // Note: we don't have to worry about HandleDirty() because we are setting // prefs in the content process that have come from the parent process. if (valueChanged) { - NotifyCallbacks(prefName); + if (pref) { + NotifyCallbacks(prefName, PrefWrapper(pref)); + } else { + NotifyCallbacks(prefName); + } } } @@ -3744,10 +4363,9 @@ Preferences::GetDefaultBranch(const char* aPrefRoot, nsIPrefBranch** aRetVal) NS_IMETHODIMP Preferences::ReadStats(nsIPrefStatsCallback* aCallback) { -#ifdef DEBUG - for (auto iter = gHashTable->Iter(); !iter.Done(); iter.Next()) { - PrefEntry* entry = static_cast(iter.Get()); - aCallback->Visit(entry->mPref->Name(), entry->mAccessCount); +#ifdef ACCESS_COUNTS + for (auto iter = gAccessCounts->Iter(); !iter.Done(); iter.Next()) { + aCallback->Visit(iter.Key(), iter.Data()); } return NS_OK; @@ -3759,10 +4377,8 @@ Preferences::ReadStats(nsIPrefStatsCallback* aCallback) NS_IMETHODIMP Preferences::ResetStats() { -#ifdef DEBUG - for (auto iter = gHashTable->Iter(); !iter.Done(); iter.Next()) { - static_cast(iter.Get())->mAccessCount = 0; - } +#ifdef ACCESS_COUNTS + gAccessCounts->Clear(); return NS_OK; #else return NS_ERROR_NOT_IMPLEMENTED; @@ -4130,6 +4746,28 @@ Preferences::InitInitialObjects(bool aIsStartup) // will override the former. StaticPrefs::InitAll(aIsStartup); + if (!XRE_IsParentProcess()) { + MOZ_ASSERT(gSharedMap); + + // We got our initial preference values from the content process, so we + // don't need to add them to the DB. For static var caches, though, the + // current preference values may differ from their static defaults. So we + // still need to notify callbacks for each of our shared prefs which have + // user values. + // + // While it is technically also possible for the default values to have + // changed at runtime, and therefore not match the static defaults, we don't + // support that for static preferences in this configuration, and therefore + // ignore the possibility. + for (auto& pref : gSharedMap->Iter()) { + if (pref.HasUserValue() || pref.IsLocked()) { + NotifyCallbacks(pref.Name(), PrefWrapper(pref)); + } + } + + return Ok(); + } + // In the omni.jar case, we load the following prefs: // - jar:$gre/omni.jar!/greprefs.js // - jar:$gre/omni.jar!/defaults/pref/*.js @@ -4316,8 +4954,9 @@ Preferences::GetBool(const char* aPrefName, bool* aResult, PrefValueKind aKind) MOZ_ASSERT(aResult); NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); - Pref* pref = pref_HashTableLookup(aPrefName); - return pref ? pref->GetBoolValue(aKind, aResult) : NS_ERROR_UNEXPECTED; + Maybe pref = pref_Lookup(aPrefName); + return pref.isSome() ? pref->GetBoolValue(aKind, aResult) + : NS_ERROR_UNEXPECTED; } /* static */ nsresult @@ -4328,8 +4967,9 @@ Preferences::GetInt(const char* aPrefName, MOZ_ASSERT(aResult); NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); - Pref* pref = pref_HashTableLookup(aPrefName); - return pref ? pref->GetIntValue(aKind, aResult) : NS_ERROR_UNEXPECTED; + Maybe pref = pref_Lookup(aPrefName); + return pref.isSome() ? pref->GetIntValue(aKind, aResult) + : NS_ERROR_UNEXPECTED; } /* static */ nsresult @@ -4356,8 +4996,9 @@ Preferences::GetCString(const char* aPrefName, aResult.SetIsVoid(true); - Pref* pref = pref_HashTableLookup(aPrefName); - return pref ? pref->GetCStringValue(aKind, aResult) : NS_ERROR_UNEXPECTED; + Maybe pref = pref_Lookup(aPrefName); + return pref.isSome() ? pref->GetCStringValue(aKind, aResult) + : NS_ERROR_UNEXPECTED; } /* static */ nsresult @@ -4490,14 +5131,15 @@ Preferences::Lock(const char* aPrefName) ENSURE_PARENT_PROCESS("Lock", aPrefName); NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); - Pref* pref = pref_HashTableLookup(aPrefName); - if (!pref) { - return NS_ERROR_UNEXPECTED; - } + Pref* pref; + MOZ_TRY_VAR(pref, + pref_LookupForModify(aPrefName, [](const PrefWrapper& aPref) { + return !aPref.IsLocked(); + })); - if (!pref->IsLocked()) { + if (pref) { pref->SetIsLocked(true); - NotifyCallbacks(aPrefName); + NotifyCallbacks(aPrefName, PrefWrapper(pref)); } return NS_OK; @@ -4509,14 +5151,15 @@ Preferences::Unlock(const char* aPrefName) ENSURE_PARENT_PROCESS("Unlock", aPrefName); NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); - Pref* pref = pref_HashTableLookup(aPrefName); - if (!pref) { - return NS_ERROR_UNEXPECTED; - } + Pref* pref; + MOZ_TRY_VAR(pref, + pref_LookupForModify(aPrefName, [](const PrefWrapper& aPref) { + return aPref.IsLocked(); + })); - if (pref->IsLocked()) { + if (pref) { pref->SetIsLocked(false); - NotifyCallbacks(aPrefName); + NotifyCallbacks(aPrefName, PrefWrapper(pref)); } return NS_OK; @@ -4527,8 +5170,8 @@ Preferences::IsLocked(const char* aPrefName) { NS_ENSURE_TRUE(InitStaticMembers(), false); - Pref* pref = pref_HashTableLookup(aPrefName); - return pref && pref->IsLocked(); + Maybe pref = pref_Lookup(aPrefName); + return pref.isSome() && pref->IsLocked(); } /* static */ nsresult @@ -4537,16 +5180,27 @@ Preferences::ClearUser(const char* aPrefName) ENSURE_PARENT_PROCESS("ClearUser", aPrefName); NS_ENSURE_TRUE(InitStaticMembers(), NS_ERROR_NOT_AVAILABLE); - PrefEntry* entry = pref_HashTableLookupInner(aPrefName); - Pref* pref; - if (entry && (pref = entry->mPref) && pref->HasUserValue()) { + auto result = pref_LookupForModify( + aPrefName, [](const PrefWrapper& aPref) { return aPref.HasUserValue(); }); + if (result.isErr()) { + return NS_OK; + } + + if (Pref* pref = result.unwrap()) { pref->ClearUserValue(); if (!pref->HasDefaultValue()) { - gHashTable->RemoveEntry(entry); + if (!gSharedMap || !gSharedMap->Has(pref->Name())) { + gHashTable->Remove(aPrefName); + } else { + pref->SetType(PrefType::None); + } + + NotifyCallbacks(aPrefName); + } else { + NotifyCallbacks(aPrefName, PrefWrapper(pref)); } - NotifyCallbacks(aPrefName); Preferences::HandleDirty(); } return NS_OK; @@ -4557,8 +5211,8 @@ Preferences::HasUserValue(const char* aPrefName) { NS_ENSURE_TRUE(InitStaticMembers(), false); - Pref* pref = pref_HashTableLookup(aPrefName); - return pref && pref->HasUserValue(); + Maybe pref = pref_Lookup(aPrefName); + return pref.isSome() && pref->HasUserValue(); } /* static */ int32_t @@ -4566,8 +5220,12 @@ Preferences::GetType(const char* aPrefName) { NS_ENSURE_TRUE(InitStaticMembers(), nsIPrefBranch::PREF_INVALID); - Pref* pref; - if (!gHashTable || !(pref = pref_HashTableLookup(aPrefName))) { + if (!gHashTable) { + return PREF_INVALID; + } + + Maybe pref = pref_Lookup(aPrefName); + if (!pref.isSome()) { return PREF_INVALID; } @@ -5106,9 +5764,12 @@ static void InitVarCachePref(const nsACString& aName, bool* aCache, bool aDefaultValue, - bool aIsStartup) + bool aIsStartup, + bool aSetValue) { - SetPref_bool(PromiseFlatCString(aName).get(), aDefaultValue); + if (aSetValue) { + SetPref_bool(PromiseFlatCString(aName).get(), aDefaultValue); + } *aCache = aDefaultValue; if (aIsStartup) { Preferences::AddBoolVarCache(aCache, aName, aDefaultValue, true); @@ -5120,9 +5781,12 @@ static void InitVarCachePref(const nsACString& aName, Atomic* aCache, bool aDefaultValue, - bool aIsStartup) + bool aIsStartup, + bool aSetValue) { - SetPref_bool(PromiseFlatCString(aName).get(), aDefaultValue); + if (aSetValue) { + SetPref_bool(PromiseFlatCString(aName).get(), aDefaultValue); + } *aCache = aDefaultValue; if (aIsStartup) { Preferences::AddAtomicBoolVarCache(aCache, aName, aDefaultValue, true); @@ -5134,9 +5798,12 @@ MOZ_MAYBE_UNUSED static void InitVarCachePref(const nsACString& aName, int32_t* aCache, int32_t aDefaultValue, - bool aIsStartup) + bool aIsStartup, + bool aSetValue) { - SetPref_int32_t(PromiseFlatCString(aName).get(), aDefaultValue); + if (aSetValue) { + SetPref_int32_t(PromiseFlatCString(aName).get(), aDefaultValue); + } *aCache = aDefaultValue; if (aIsStartup) { Preferences::AddIntVarCache(aCache, aName, aDefaultValue, true); @@ -5148,9 +5815,12 @@ static void InitVarCachePref(const nsACString& aName, Atomic* aCache, int32_t aDefaultValue, - bool aIsStartup) + bool aIsStartup, + bool aSetValue) { - SetPref_int32_t(PromiseFlatCString(aName).get(), aDefaultValue); + if (aSetValue) { + SetPref_int32_t(PromiseFlatCString(aName).get(), aDefaultValue); + } *aCache = aDefaultValue; if (aIsStartup) { Preferences::AddAtomicIntVarCache(aCache, aName, aDefaultValue, true); @@ -5161,10 +5831,13 @@ static void InitVarCachePref(const nsACString& aName, uint32_t* aCache, uint32_t aDefaultValue, - bool aIsStartup) + bool aIsStartup, + bool aSetValue) { - SetPref_int32_t(PromiseFlatCString(aName).get(), - static_cast(aDefaultValue)); + if (aSetValue) { + SetPref_int32_t(PromiseFlatCString(aName).get(), + static_cast(aDefaultValue)); + } *aCache = aDefaultValue; if (aIsStartup) { Preferences::AddUintVarCache(aCache, aName, aDefaultValue, true); @@ -5176,10 +5849,13 @@ static void InitVarCachePref(const nsACString& aName, Atomic* aCache, uint32_t aDefaultValue, - bool aIsStartup) + bool aIsStartup, + bool aSetValue) { - SetPref_int32_t(PromiseFlatCString(aName).get(), - static_cast(aDefaultValue)); + if (aSetValue) { + SetPref_int32_t(PromiseFlatCString(aName).get(), + static_cast(aDefaultValue)); + } *aCache = aDefaultValue; if (aIsStartup) { Preferences::AddAtomicUintVarCache(aCache, aName, aDefaultValue, true); @@ -5191,9 +5867,12 @@ MOZ_MAYBE_UNUSED static void InitVarCachePref(const nsACString& aName, float* aCache, float aDefaultValue, - bool aIsStartup) + bool aIsStartup, + bool aSetValue) { - SetPref_float(PromiseFlatCString(aName).get(), aDefaultValue); + if (aSetValue) { + SetPref_float(PromiseFlatCString(aName).get(), aDefaultValue); + } *aCache = aDefaultValue; if (aIsStartup) { Preferences::AddFloatVarCache(aCache, aName, aDefaultValue, true); @@ -5203,27 +5882,35 @@ InitVarCachePref(const nsACString& aName, /* static */ void StaticPrefs::InitAll(bool aIsStartup) { -// For prefs like these: -// -// PREF("foo.bar.baz", bool, true) -// VARCACHE_PREF("my.varcache", my_varcache, int32_t, 99) -// -// we generate registration calls: -// -// SetPref_bool("foo.bar.baz", true); -// InitVarCachePref("my.varcache", &StaticPrefs::sVarCache_my_varcache, 99, -// aIsStartup); -// -// The SetPref_*() functions have a type suffix to avoid ambiguity between -// prefs having int32_t and float default values. That suffix is not needed for -// the InitVarCachePref() functions because they take a pointer parameter, -// which prevents automatic int-to-float coercion. -#define PREF(name, cpp_type, value) SetPref_##cpp_type(name, value); + // For prefs like these: + // + // PREF("foo.bar.baz", bool, true) + // VARCACHE_PREF("my.varcache", my_varcache, int32_t, 99) + // + // we generate registration calls: + // + // if (isParent) + // SetPref_bool("foo.bar.baz", true); + // InitVarCachePref("my.varcache", &StaticPrefs::sVarCache_my_varcache, 99, + // aIsStartup); + // + // The SetPref_*() functions have a type suffix to avoid ambiguity between + // prefs having int32_t and float default values. That suffix is not needed + // for the InitVarCachePref() functions because they take a pointer parameter, + // which prevents automatic int-to-float coercion. + // + // In content processes, we rely on the parent to send us the correct initial + // values via shared memory, so we do not re-initialize them here. + bool isParent = XRE_IsParentProcess(); +#define PREF(name, cpp_type, value) \ + if (isParent) \ + SetPref_##cpp_type(name, value); #define VARCACHE_PREF(name, id, cpp_type, value) \ InitVarCachePref(NS_LITERAL_CSTRING(name), \ &StaticPrefs::sVarCache_##id, \ value, \ - aIsStartup); + aIsStartup, \ + isParent); #include "mozilla/StaticPrefList.h" #undef PREF #undef VARCACHE_PREF diff --git a/modules/libpref/Preferences.h b/modules/libpref/Preferences.h index 7be5efed45cd..946b1bb866ec 100644 --- a/modules/libpref/Preferences.h +++ b/modules/libpref/Preferences.h @@ -39,11 +39,44 @@ class Pref; class PrefValue; } // namespace dom +namespace ipc { +class FileDescriptor; +} // namespace ipc + struct PrefsSizes; +// Xlib.h defines Bool as a macro constant. Don't try to define this enum if +// it's already been included. +#ifndef Bool + +// Keep this in sync with PrefType in parser/src/lib.rs. +enum class PrefType : uint8_t +{ + None = 0, // only used when neither the default nor user value is set + String = 1, + Int = 2, + Bool = 3, +}; + +#endif + #ifdef XP_UNIX +// We need to send two shared memory descriptors to every child process: +// +// 1) A read-only/write-protected snapshot of the initial state of the +// preference database. This memory is shared between all processes, and +// therefore cannot be modified once it has been created. +// +// 2) A set of changes on top of the snapshot, containing the current values of +// all preferences which have changed since it was created. +// +// Since the second set will be different for every process, and the first set +// cannot be modified, it is unfortunately not possible to combine them into a +// single file descriptor. +// // XXX: bug 1440207 is about improving how fixed fds such as this are used. static const int kPrefsFileDescriptor = 8; +static const int kPrefMapFileDescriptor = 9; #endif // Keep this in sync with PrefType in parser/src/lib.rs. @@ -481,6 +514,9 @@ public: static void SerializePreferences(nsCString& aStr); static void DeserializePreferences(char* aStr, size_t aPrefsLen); + static mozilla::ipc::FileDescriptor EnsureSnapshot(size_t* aSize); + static void InitSnapshot(const mozilla::ipc::FileDescriptor&, size_t aSize); + // When a single pref is changed in the parent process, these methods are // used to pass the update to content processes. static void GetPreference(dom::Pref* aPref); diff --git a/modules/libpref/SharedPrefMap.cpp b/modules/libpref/SharedPrefMap.cpp new file mode 100644 index 000000000000..6a11895dd5a9 --- /dev/null +++ b/modules/libpref/SharedPrefMap.cpp @@ -0,0 +1,252 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* vim: set ts=8 sts=4 et sw=4 tw=99: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "SharedPrefMap.h" + +#include "mozilla/dom/ipc/MemMapSnapshot.h" + +#include "mozilla/BinarySearch.h" +#include "mozilla/ResultExtensions.h" +#include "mozilla/ipc/FileDescriptor.h" + +using namespace mozilla::loader; + +namespace mozilla { + +using namespace ipc; + +static inline size_t +GetAlignmentOffset(size_t aOffset, size_t aAlign) +{ + auto mod = aOffset % aAlign; + return mod ? aAlign - mod : 0; +} + +SharedPrefMap::SharedPrefMap(const FileDescriptor& aMapFile, size_t aMapSize) +{ + auto result = mMap.initWithHandle(aMapFile, aMapSize); + MOZ_RELEASE_ASSERT(result.isOk()); + // We return literal nsCStrings pointing to the mapped data for preference + // names and string values, which means that we may still have references to + // the mapped data even after this instance is destroyed. That means that we + // need to keep the mapping alive until process shutdown, in order to be safe. + mMap.setPersistent(); +} + +SharedPrefMap::SharedPrefMap(SharedPrefMapBuilder&& aBuilder) +{ + auto result = aBuilder.Finalize(mMap); + MOZ_RELEASE_ASSERT(result.isOk()); + mMap.setPersistent(); +} + +mozilla::ipc::FileDescriptor +SharedPrefMap::CloneFileDescriptor() const +{ + return mMap.cloneHandle(); +} + +bool +SharedPrefMap::Has(const char* aKey) const +{ + size_t index; + return Find(aKey, &index); +} + +Maybe +SharedPrefMap::Get(const char* aKey) const +{ + Maybe result; + + size_t index; + if (Find(aKey, &index)) { + result.emplace(Pref{ this, &Entries()[index] }); + } + + return result; +} + +bool +SharedPrefMap::Find(const char* aKey, size_t* aIndex) const +{ + const auto& keys = KeyTable(); + + return BinarySearchIf(Entries(), + 0, + EntryCount(), + [&](const Entry& aEntry) { + return strcmp(aKey, keys.GetBare(aEntry.mKey)); + }, + aIndex); +} + +void +SharedPrefMapBuilder::Add(const char* aKey, + const Flags& aFlags, + bool aDefaultValue, + bool aUserValue) +{ + mEntries.AppendElement(Entry{ + aKey, + mKeyTable.Add(aKey), + { aDefaultValue, aUserValue }, + uint8_t(PrefType::Bool), + aFlags.mHasDefaultValue, + aFlags.mHasUserValue, + aFlags.mIsSticky, + aFlags.mIsLocked, + }); +} + +void +SharedPrefMapBuilder::Add(const char* aKey, + const Flags& aFlags, + int32_t aDefaultValue, + int32_t aUserValue) +{ + ValueIdx index; + if (aFlags.mHasUserValue) { + index = mIntValueTable.Add(aDefaultValue, aUserValue); + } else { + index = mIntValueTable.Add(aDefaultValue); + } + + mEntries.AppendElement(Entry{ + aKey, + mKeyTable.Add(aKey), + { index }, + uint8_t(PrefType::Int), + aFlags.mHasDefaultValue, + aFlags.mHasUserValue, + aFlags.mIsSticky, + aFlags.mIsLocked, + }); +} + +void +SharedPrefMapBuilder::Add(const char* aKey, + const Flags& aFlags, + const nsCString& aDefaultValue, + const nsCString& aUserValue) +{ + ValueIdx index; + StringTableEntry defaultVal = mValueStringTable.Add(aDefaultValue); + if (aFlags.mHasUserValue) { + StringTableEntry userVal = mValueStringTable.Add(aUserValue); + index = mStringValueTable.Add(defaultVal, userVal); + } else { + index = mStringValueTable.Add(defaultVal); + } + + mEntries.AppendElement(Entry{ + aKey, + mKeyTable.Add(aKey), + { index }, + uint8_t(PrefType::String), + aFlags.mHasDefaultValue, + aFlags.mHasUserValue, + aFlags.mIsSticky, + aFlags.mIsLocked, + }); +} + +Result +SharedPrefMapBuilder::Finalize(loader::AutoMemMap& aMap) +{ + using Header = SharedPrefMap::Header; + + // Create an array of entry pointers for the entry array, and sort it by + // preference name prior to serialization, so that entries can be looked up + // using binary search. + nsTArray entries(mEntries.Length()); + for (auto& entry : mEntries) { + entries.AppendElement(&entry); + } + entries.Sort([](const Entry* aA, const Entry* aB) { + return strcmp(aA->mKeyString, aB->mKeyString); + }); + + Header header = { uint32_t(entries.Length()) }; + + size_t offset = sizeof(header); + offset += GetAlignmentOffset(offset, alignof(Header)); + + offset += entries.Length() * sizeof(SharedPrefMap::Entry); + + header.mKeyStrings.mOffset = offset; + header.mKeyStrings.mSize = mKeyTable.Size(); + offset += header.mKeyStrings.mSize; + + offset += GetAlignmentOffset(offset, mIntValueTable.Alignment()); + header.mUserIntValues.mOffset = offset; + header.mUserIntValues.mSize = mIntValueTable.UserSize(); + offset += header.mUserIntValues.mSize; + + offset += GetAlignmentOffset(offset, mIntValueTable.Alignment()); + header.mDefaultIntValues.mOffset = offset; + header.mDefaultIntValues.mSize = mIntValueTable.DefaultSize(); + offset += header.mDefaultIntValues.mSize; + + offset += GetAlignmentOffset(offset, mStringValueTable.Alignment()); + header.mUserStringValues.mOffset = offset; + header.mUserStringValues.mSize = mStringValueTable.UserSize(); + offset += header.mUserStringValues.mSize; + + offset += GetAlignmentOffset(offset, mStringValueTable.Alignment()); + header.mDefaultStringValues.mOffset = offset; + header.mDefaultStringValues.mSize = mStringValueTable.DefaultSize(); + offset += header.mDefaultStringValues.mSize; + + header.mValueStrings.mOffset = offset; + header.mValueStrings.mSize = mValueStringTable.Size(); + offset += header.mValueStrings.mSize; + + MemMapSnapshot mem; + MOZ_TRY(mem.Init(offset)); + + auto headerPtr = mem.Get
(); + headerPtr[0] = header; + + auto* entryPtr = reinterpret_cast(&headerPtr[1]); + for (auto* entry : entries) { + *entryPtr = { + entry->mKey, GetValue(*entry), + entry->mType, entry->mHasDefaultValue, + entry->mHasUserValue, entry->mIsSticky, + entry->mIsLocked, + }; + entryPtr++; + } + + auto ptr = mem.Get(); + + mKeyTable.Write( + { &ptr[header.mKeyStrings.mOffset], header.mKeyStrings.mSize }); + + mValueStringTable.Write( + { &ptr[header.mValueStrings.mOffset], header.mValueStrings.mSize }); + + mIntValueTable.WriteDefaultValues( + { &ptr[header.mDefaultIntValues.mOffset], header.mDefaultIntValues.mSize }); + mIntValueTable.WriteUserValues( + { &ptr[header.mUserIntValues.mOffset], header.mUserIntValues.mSize }); + + mStringValueTable.WriteDefaultValues( + { &ptr[header.mDefaultStringValues.mOffset], + header.mDefaultStringValues.mSize }); + mStringValueTable.WriteUserValues( + { &ptr[header.mUserStringValues.mOffset], header.mUserStringValues.mSize }); + + mKeyTable.Clear(); + mValueStringTable.Clear(); + mIntValueTable.Clear(); + mStringValueTable.Clear(); + mEntries.Clear(); + + return mem.Finalize(aMap); +} + +} // mozilla diff --git a/modules/libpref/SharedPrefMap.h b/modules/libpref/SharedPrefMap.h new file mode 100644 index 000000000000..543f54ed6151 --- /dev/null +++ b/modules/libpref/SharedPrefMap.h @@ -0,0 +1,895 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* vim: set ts=8 sts=4 et sw=4 tw=99: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef dom_ipc_SharedPrefMap_h +#define dom_ipc_SharedPrefMap_h + +#include "mozilla/AutoMemMap.h" +#include "mozilla/HashFunctions.h" +#include "mozilla/Preferences.h" +#include "mozilla/Result.h" +#include "mozilla/dom/ipc/StringTable.h" +#include "nsDataHashtable.h" + +namespace mozilla { + +// The approximate number of preferences expected to be in an ordinary +// preferences database. +// +// This number is used to determine initial allocation sizes for data structures +// when building the shared preference map, and should be slightly higher than +// the expected number of preferences in an ordinary database to avoid +// unnecessary reallocations/rehashes. +constexpr size_t kExpectedPrefCount = 4000; + +class SharedPrefMapBuilder; + +// This class provides access to a compact, read-only copy of a preference +// database, backed by a shared memory buffer which can be shared between +// processes. All state data for the database is stored in the shared memory +// region, so individual instances require no dynamic memory allocation. +// +// Further, all strings returned from this API are nsLiteralCStrings with +// pointers into the shared memory region, which means that they can be copied +// into new nsCString instances without additional allocations. For instance, +// the following (where `pref` is a Pref object) will not cause any string +// copies, memory allocations, or atomic refcount changes: +// +// nsCString prefName(pref.NameString()); +// +// whereas if we returned a nsDependentCString or a dynamically allocated +// nsCString, it would. +// +// The set of entries is stored in sorted order by preference name, so look-ups +// are done by binary search. This means that look-ups have O(log n) complexity, +// rather than the O(1) complexity of a dynamic hashtable. Consumers should keep +// this in mind when planning their accesses. +// +// Important: The mapped memory created by this class is persistent. Once an +// instance has been initialized, the memory that it allocates can never be +// freed before process shutdown. Do not use it for short-lived mappings. +class SharedPrefMap +{ + using FileDescriptor = mozilla::ipc::FileDescriptor; + + friend class SharedPrefMapBuilder; + + // Describes a block of memory within the shared memory region. + struct DataBlock + { + // The byte offset from the start of the shared memory region to the start + // of the block. + size_t mOffset; + // The size of the block, in bytes. This is typically used only for bounds + // checking in debug builds. + size_t mSize; + }; + + // Describes the contents of the shared memory region, which is laid-out as + // follows: + // + // - The Header struct + // + // - An array of Entry structs with mEntryCount elements, lexicographically + // sorted by preference name. + // + // - A set of data blocks, with offsets and sizes described by the DataBlock + // entries in the header, described below. + // + // Each entry stores its name string and values as indices into these blocks, + // as documented in the Entry struct, but with some important optimizations: + // + // - Boolean values are always stored inline. Both the default and user + // values can be retrieved directly from the entry. Other types have only + // one value index, and their values appear at the same indices in the + // default and user value arrays. + // + // Aside from reducing our memory footprint, this space-efficiency means + // that we can fit more entries in the CPU cache at once, and reduces the + // number of likely cache misses during lookups. + // + // - Key strings are stored in a separate string table from value strings. As + // above, this makes it more likely that the strings we need will be + // available in the CPU cache during lookups by not interleaving them with + // extraneous data. + // + // - Default and user values are stored in separate arrays. Entries with user + // values always appear before entries with default values in the value + // arrays, and entries without user values do not have entries in the user + // array at all. Since the same index is used for both arrays, this means + // that entries with a default value but no user value do not allocate any + // space to store their user value. + // + // - For preferences with no user value, the entries in the default value are + // de-duplicated. All preferences with the same default value (and no user + // value) point to the same index in the default value array. + // + // + // For example, a preference database containing: + // + // +---------+-------------------------------+-------------------------------+ + // | Name | Default Value | User Value | | + // +---------+---------------+---------------+-------------------------------+ + // | string1 | "meh" | "hem" | | + // | string2 | | "b" | | + // | string3 | "a" | | | + // | string4 | "foo" | | | + // | string5 | "foo" | | | + // | string6 | "meh" | | | + // +---------+---------------+---------------+-------------------------------+ + // | bool1 | false | true | | + // | bool2 | | false | | + // | bool3 | true | | | + // +---------+---------------+---------------+-------------------------------+ + // | int1 | 18 | 16 | | + // | int2 | | 24 | | + // | int3 | 42 | | | + // | int4 | 12 | | | + // | int5 | 12 | | | + // | int6 | 18 | | | + // +---------+---------------+---------------+-------------------------------+ + // + // Results in a database that looks like: + // + // +-------------------------------------------------------------------------+ + // | Header: | + // +-------------------------------------------------------------------------+ + // | mEntryCount = 15 | + // | ... | + // +-------------------------------------------------------------------------+ + // + // +-------------------------------------------------------------------------+ + // | Key strings: | + // +--------+----------------------------------------------------------------+ + // | Offset | Value | + // +--------+----------------------------------------------------------------+ + // | 0 | string1\0 | + // | 8 | string2\0 | + // | 16 | string3\0 | + // | 24 | string4\0 | + // | 32 | string5\0 | + // | 40 | string6\0 | + // | 48 | bool1\0 | + // | 54 | bool2\0 | + // | 60 | bool3\0 | + // | 66 | int1\0 | + // | 71 | int2\0 | + // | 76 | int3\0 | + // | 81 | int4\0 | + // | 86 | int6\0 | + // | 91 | int6\0 | + // +--------+----------------------------------------------------------------+ + // + // +-------------------------------------------------------------------------+ + // | Entries: | + // +---------------------+------+------------+------------+------------------+ + // | Key[1] | Type | HasDefault | HasUser | Value | + // +---------------------+------+------------+------------+------------------+ + // | K["bool1", 48, 5] | 3 | true | true | { false, true } | + // | K["bool2", 54, 5] | 3 | false | true | { 0, false } | + // | K["bool3", 60, 5] | 3 | true | false | { true, 0 } | + // | K["int1", 66, 4] | 2 | true | true | 0 | + // | K["int2", 71, 4] | 2 | false | true | 1 | + // | K["int3", 76, 4] | 2 | true | false | 2 | + // | K["int4", 81, 4] | 2 | true | false | 3 | + // | K["int5", 86, 4] | 2 | true | false | 3 | + // | K["int6", 91, 4] | 2 | true | false | 4 | + // | K["string1", 0, 6] | 1 | true | true | 0 | + // | K["string2", 8, 6] | 1 | false | true | 1 | + // | K["string3", 16, 6] | 1 | true | false | 2 | + // | K["string4", 24, 6] | 1 | true | false | 3 | + // | K["string5", 32, 6] | 1 | true | false | 3 | + // | K["string6", 40, 6] | 1 | true | false | 4 | + // +---------------------+------+------------+------------+------------------+ + // | [1]: Encoded as an offset into the key table and a length. Specified | + // | as K[string, offset, length] for clarity. | + // +-------------------------------------------------------------------------+ + // + // +------------------------------------+------------------------------------+ + // | User integer values | Default integer values | + // +-------+----------------------------+-------+----------------------------+ + // | Index | Contents | Index | Contents | + // +-------+----------------------------+-------+----------------------------+ + // | 0 | 16 | 0 | 18 | + // | 1 | 24 | 1 | | + // | | | 2 | 42 | + // | | | 3 | 12 | + // | | | 4 | 18 | + // +-------+----------------------------+-------+----------------------------+ + // | * Note: Tables are laid out sequentially in memory, but displayed | + // | here side-by-side for clarity. | + // +-------------------------------------------------------------------------+ + // + // +------------------------------------+------------------------------------+ + // | User string values | Default string values | + // +-------+----------------------------+-------+----------------------------+ + // | Index | Contents[1] | Index | Contents[1] | + // +-------+----------------------------+-------+----------------------------+ + // | 0 | V["hem", 0, 3] | 0 | V["meh", 4, 3] | + // | 1 | V["b", 8, 1] | 1 | | + // | | | 2 | V["a", 10, 1] | + // | | | 3 | V["foo", 12, 3] | + // | | | 4 | V["meh", 4, 3] | + // |-------+----------------------------+-------+----------------------------+ + // | [1]: Encoded as an offset into the value table and a length. Specified | + // | as V[string, offset, length] for clarity. | + // +-------------------------------------------------------------------------+ + // | * Note: Tables are laid out sequentially in memory, but displayed | + // | here side-by-side for clarity. | + // +-------------------------------------------------------------------------+ + // + // +-------------------------------------------------------------------------+ + // | Value strings: | + // +--------+----------------------------------------------------------------+ + // | Offset | Value | + // +--------+----------------------------------------------------------------+ + // | 0 | hem\0 | + // | 4 | meh\0 | + // | 8 | b\0 | + // | 10 | a\0 | + // | 12 | foo\0 | + // +--------+----------------------------------------------------------------+ + struct Header + { + // The number of entries in this map. + uint32_t mEntryCount; + + // The StringTable data block for preference name strings, which act as keys + // in the map. + DataBlock mKeyStrings; + + // The int32_t arrays of user and default int preference values. Entries in + // the map store their values as indices into these arrays. + DataBlock mUserIntValues; + DataBlock mDefaultIntValues; + + // The StringTableEntry arrays of user and default string preference values. + // + // Strings are stored as StringTableEntry structs with character offsets + // into the mValueStrings string table and their corresponding lenghts. + // + // Entries in the map, likewise, store their string values as indices into + // these arrays. + DataBlock mUserStringValues; + DataBlock mDefaultStringValues; + + // The StringTable data block for string preference values, referenced by + // the above two data blocks. + DataBlock mValueStrings; + }; + + using StringTableEntry = mozilla::dom::ipc::StringTableEntry; + + // Represents a preference value, as either a pair of boolean values, or an + // index into one of the above value arrays. + union Value { + Value(bool aDefaultValue, bool aUserValue) + : mDefaultBool(aDefaultValue) + , mUserBool(aUserValue) + { + } + + MOZ_IMPLICIT Value(uint16_t aIndex) + : mIndex(aIndex) + { + } + + // The index of this entry in the value arrays. + // + // User and default preference values have the same indices in their + // respective arrays. However, entries without a user value are not + // guaranteed to have space allocated for them in the user value array, and + // likewise for preferences without default values in the default value + // array. This means that callers must only access value entries for entries + // which claim to have a value of that type. + uint16_t mIndex; + struct + { + bool mDefaultBool; + bool mUserBool; + }; + }; + + // Represents a preference entry in the map, containing its name, type info, + // flags, and a reference to its value. + struct Entry + { + // A pointer to the preference name in the KeyTable string table. + StringTableEntry mKey; + + // The preference's value, either as a pair of booleans, or an index into + // the value arrays. Please see the documentation for the Value struct + // above. + Value mValue; + + // The preference's type, as a PrefType enum value. This must *never* be + // PrefType::None for values in a shared array. + uint8_t mType : 2; + // True if the preference has a default value. Callers must not attempt to + // access the entry's default value if this is false. + uint8_t mHasDefaultValue : 1; + // True if the preference has a user value. Callers must not attempt to + // access the entry's user value if this is false. + uint8_t mHasUserValue : 1; + // True if the preference is sticky, as defined by the preference service. + uint8_t mIsSticky : 1; + // True if the preference is locked, as defined by the preference service. + uint8_t mIsLocked : 1; + }; + +public: + NS_INLINE_DECL_REFCOUNTING(SharedPrefMap) + + // A temporary wrapper class for accessing entries in the array. Instances of + // this class are valid as long as SharedPrefMap instance is alive, but + // generally should not be stored long term, or allocated on the heap. + // + // The class is implemented as two pointers, one to the SharedPrefMap + // instance, and one to the Entry that corresponds to the preference, and is + // meant to be cheaply returned by value from preference lookups and + // iterators. All property accessors lazily fetch the appropriate values from + // the shared memory region. + class MOZ_STACK_CLASS Pref final + { + public: + const char* Name() const { return mMap->KeyTable().GetBare(mEntry->mKey); } + + nsCString NameString() const { return mMap->KeyTable().Get(mEntry->mKey); } + + PrefType Type() const + { + MOZ_ASSERT(PrefType(mEntry->mType) != PrefType::None); + return PrefType(mEntry->mType); + } + + bool HasDefaultValue() const { return mEntry->mHasDefaultValue; } + bool HasUserValue() const { return mEntry->mHasUserValue; } + bool IsLocked() const { return mEntry->mIsLocked; } + bool IsSticky() const { return mEntry->mIsSticky; } + + bool GetBoolValue(PrefValueKind aKind = PrefValueKind::User) const + { + MOZ_ASSERT(Type() == PrefType::Bool); + MOZ_ASSERT(aKind == PrefValueKind::Default ? HasDefaultValue() + : HasUserValue()); + + return aKind == PrefValueKind::Default ? mEntry->mValue.mDefaultBool + : mEntry->mValue.mUserBool; + } + + int32_t GetIntValue(PrefValueKind aKind = PrefValueKind::User) const + { + MOZ_ASSERT(Type() == PrefType::Int); + MOZ_ASSERT(aKind == PrefValueKind::Default ? HasDefaultValue() + : HasUserValue()); + + return aKind == PrefValueKind::Default + ? mMap->DefaultIntValues()[mEntry->mValue.mIndex] + : mMap->UserIntValues()[mEntry->mValue.mIndex]; + } + + private: + const StringTableEntry& GetStringEntry(PrefValueKind aKind) const + { + MOZ_ASSERT(Type() == PrefType::String); + MOZ_ASSERT(aKind == PrefValueKind::Default ? HasDefaultValue() + : HasUserValue()); + + return aKind == PrefValueKind::Default + ? mMap->DefaultStringValues()[mEntry->mValue.mIndex] + : mMap->UserStringValues()[mEntry->mValue.mIndex]; + } + + public: + nsCString GetStringValue(PrefValueKind aKind = PrefValueKind::User) const + { + return mMap->ValueTable().Get(GetStringEntry(aKind)); + } + + const char* GetBareStringValue( + PrefValueKind aKind = PrefValueKind::User) const + { + return mMap->ValueTable().GetBare(GetStringEntry(aKind)); + } + + // Returns the entry's index in the map, as understood by GetKeyAt() and + // GetValueAt(). + size_t Index() const { return mEntry - mMap->Entries().get(); } + + bool operator==(const Pref& aPref) const { return mEntry == aPref.mEntry; } + bool operator!=(const Pref& aPref) const { return !(*this == aPref); } + + // This is odd, but necessary in order for the C++ range iterator protocol + // to work here. + Pref& operator*() { return *this; } + + // Updates this wrapper to point to the next entry in the map. This should + // not be attempted unless Index() is less than the map's Count(). + Pref& operator++() + { + mEntry++; + return *this; + } + + Pref(const Pref& aPref) = default; + + protected: + friend class SharedPrefMap; + + Pref(const SharedPrefMap* aPrefMap, const Entry* aEntry) + : mMap(aPrefMap) + , mEntry(aEntry) + { + } + + private: + const SharedPrefMap* const mMap; + const Entry* mEntry; + }; + + // Note: These constructors are infallible, because the preference database is + // critical to platform functionality, and we cannot operate without it. + SharedPrefMap(const FileDescriptor&, size_t); + explicit SharedPrefMap(SharedPrefMapBuilder&&); + + // Searches for the given preference in the map, and returns true if it + // exists. + bool Has(const char* aKey) const; + + bool Has(const nsCString& aKey) const { return Has(aKey.get()); } + + // Searches for the given preference in the map, and if it exists, returns + // a Some containing its details. + Maybe Get(const char* aKey) const; + + Maybe Get(const nsCString& aKey) const { return Get(aKey.get()); } + +private: + // Searches for an entry for the given key. If found, returns true, and + // places its index in the entry array in aIndex. + bool Find(const char* aKey, size_t* aIndex) const; + +public: + // Returns the number of entries in the map. + uint32_t Count() const { return EntryCount(); } + + // Returns the string entry at the given index. Keys are guaranteed to be + // sorted lexicographically. + // + // The given index *must* be less than the value returned by Count(). + // + // The returned value is a literal string which references the mapped memory + // region. + nsCString GetKeyAt(uint32_t aIndex) const + { + MOZ_ASSERT(aIndex < Count()); + return KeyTable().Get(Entries()[aIndex].mKey); + } + + // Returns the value for the entry at the given index. + // + // The given index *must* be less than the value returned by Count(). + // + // The returned value is valid for the lifetime of this map instance. + const Pref GetValueAt(uint32_t aIndex) const + { + MOZ_ASSERT(aIndex < Count()); + return UncheckedGetValueAt(aIndex); + } + +private: + // Returns a wrapper with a pointer to an entry without checking its bounds. + // This should only be used by range iterators, to check their end positions. + // + // Note: In debug builds, the RangePtr returned by entries will still assert + // that aIndex is no more than 1 past the last element in the array, since it + // also takes into account the ranged iteration use case. + Pref UncheckedGetValueAt(uint32_t aIndex) const + { + return { this, (Entries() + aIndex).get() }; + } + +public: + // C++ range iterator protocol. begin() and end() return references to the + // first and last entries in the array. The begin wrapper can be incremented + // until it matches the last element in the array, at which point it becomes + // invalid and the iteration is over. + Pref begin() const { return UncheckedGetValueAt(0); } + Pref end() const { return UncheckedGetValueAt(Count()); } + + // A cosmetic helper for range iteration. Returns a reference value from a + // pointer to this instance so that its .begin() and .end() methods can be + // accessed in a ranged for loop. `map->Iter()` is equivalent to `*map`, but + // makes its purpose slightly clearer. + const SharedPrefMap& Iter() const { return *this; } + + // Returns a copy of the read-only file descriptor which backs the shared + // memory region for this map. The file descriptor may be passed between + // processes, and used to construct new instances of SharedPrefMap with + // the same data as this instance. + FileDescriptor CloneFileDescriptor() const; + + // Returns the size of the mapped memory region. This size must be passed to + // the constructor when mapping the shared region in another process. + size_t MapSize() const { return mMap.size(); } + +protected: + ~SharedPrefMap() = default; + +private: + template + using StringTable = mozilla::dom::ipc::StringTable; + + // Type-safe getters for values in the shared memory region: + const Header& GetHeader() const { return mMap.get
()[0]; } + + RangedPtr Entries() const + { + return { reinterpret_cast(&GetHeader() + 1), EntryCount() }; + } + + uint32_t EntryCount() const { return GetHeader().mEntryCount; } + + template + RangedPtr GetBlock(const DataBlock& aBlock) const + { + return RangedPtr(&mMap.get()[aBlock.mOffset], + aBlock.mSize) + .ReinterpretCast(); + } + + RangedPtr DefaultIntValues() const + { + return GetBlock(GetHeader().mDefaultIntValues); + } + RangedPtr UserIntValues() const + { + return GetBlock(GetHeader().mUserIntValues); + } + + RangedPtr DefaultStringValues() const + { + return GetBlock(GetHeader().mDefaultStringValues); + } + RangedPtr UserStringValues() const + { + return GetBlock(GetHeader().mUserStringValues); + } + + StringTable KeyTable() const + { + auto& block = GetHeader().mKeyStrings; + return { { &mMap.get()[block.mOffset], block.mSize } }; + } + + StringTable ValueTable() const + { + auto& block = GetHeader().mValueStrings; + return { { &mMap.get()[block.mOffset], block.mSize } }; + } + + loader::AutoMemMap mMap; +}; + +// A helper class which builds the contiguous look-up table used by +// SharedPrefMap. Each preference in the final map is added to the builder, +// before it is finalized and transformed into a read-only snapshot. +class MOZ_RAII SharedPrefMapBuilder +{ +public: + SharedPrefMapBuilder() = default; + + // The set of flags for the preference, as documented in SharedPrefMap::Entry. + struct Flags + { + uint8_t mHasDefaultValue : 1; + uint8_t mHasUserValue : 1; + uint8_t mIsSticky : 1; + uint8_t mIsLocked : 1; + }; + + void Add(const char* aKey, + const Flags& aFlags, + bool aDefaultValue, + bool aUserValue); + + void Add(const char* aKey, + const Flags& aFlags, + int32_t aDefaultValue, + int32_t aUserValue); + + void Add(const char* aKey, + const Flags& aFlags, + const nsCString& aDefaultValue, + const nsCString& aUserValue); + + // Finalizes the binary representation of the map, writes it to a shared + // memory region, and then initializes the given AutoMemMap with a reference + // to the read-only copy of it. + // + // This should generally not be used directly by callers. The + // SharedPrefMapBuilder instance should instead be passed to the SharedPrefMap + // constructor as a move reference. + Result Finalize(loader::AutoMemMap& aMap); + +private: + using StringTableEntry = mozilla::dom::ipc::StringTableEntry; + template + using StringTableBuilder = mozilla::dom::ipc::StringTableBuilder; + + // An opaque descriptor of the index of a preference entry in a value array, + // which can be converted numeric index after the ValueTableBuilder is + // finalized. + struct ValueIdx + { + // The relative index of the entry, based on its class. Entries for + // preferences with user values appear at the value arrays. Entries with + // only default values begin after the last entry with a user value. + uint16_t mIndex; + bool mHasUserValue; + }; + + // A helper class for building default and user value arrays for preferences. + // + // As described in the SharedPrefMap class, this helper optimizes the way that + // it builds its value arrays, in that: + // + // - It stores value entries for all preferences with user values before + // entries for preferences with only default values, and allocates no + // entries for preferences with only default values in the user value array. + // Since most preferences have only default values, this dramatically + // reduces the space required for value storage. + // + // - For preferences with only default values, it de-duplicates value entries, + // and returns the same indices for all preferences with the same value. + // + // One important complication of this approach is that it means we cannot know + // the final index of any entry with only a default value until all entries + // have been added to the builder, since it depends on the final number of + // user entries in the output. + // + // To deal with this, when entries are added, we return an opaque ValueIndex + // struct, from which we can calculate the final index after the map has been + // finalized. + template + class ValueTableBuilder + { + public: + using ValueType = ValueType_; + + // Adds an entry for a preference with only a default value to the array, + // and returns an opaque descriptor for its index. + ValueIdx Add(const ValueType& aDefaultValue) + { + auto index = uint16_t(mDefaultEntries.Count()); + + auto entry = mDefaultEntries.LookupForAdd(aDefaultValue).OrInsert([&]() { + return Entry{ index, false, aDefaultValue }; + }); + + return { entry.mIndex, false }; + } + + // Adds an entry for a preference with a user value to the array. Regardless + // of whether the preference has a default value, space must be allocated + // for it. For preferences with no default value, the actual value which + // appears in the array at its value index is ignored. + ValueIdx Add(const ValueType& aDefaultValue, const ValueType& aUserValue) + { + auto index = uint16_t(mUserEntries.Length()); + + mUserEntries.AppendElement( + Entry{ index, true, aDefaultValue, aUserValue }); + + return { index, true }; + } + + // Returns the final index for an entry based on its opaque index + // descriptor. This must only be called after the caller has finished adding + // entries to the builder. + uint16_t GetIndex(const ValueIdx& aIndex) const + { + uint16_t base = aIndex.mHasUserValue ? 0 : UserCount(); + return base + aIndex.mIndex; + } + + // Writes out the array of default values at the block beginning at the + // given pointer. The block must be at least as large as the value returned + // by DefaultSize(). + void WriteDefaultValues(const RangedPtr& aBuffer) const + { + auto buffer = aBuffer.ReinterpretCast(); + + for (const auto& entry : mUserEntries) { + buffer[entry.mIndex] = entry.mDefaultValue; + } + + size_t defaultsOffset = UserCount(); + for (auto iter = mDefaultEntries.ConstIter(); !iter.Done(); iter.Next()) { + const auto& entry = iter.Data(); + buffer[defaultsOffset + entry.mIndex] = entry.mDefaultValue; + } + } + + // Writes out the array of user values at the block beginning at the + // given pointer. The block must be at least as large as the value returned + // by UserSize(). + void WriteUserValues(const RangedPtr& aBuffer) const + { + auto buffer = aBuffer.ReinterpretCast(); + + for (const auto& entry : mUserEntries) { + buffer[entry.mIndex] = entry.mUserValue; + } + } + + // These return the number of entries in the default and user value arrays, + // respectively. + uint32_t DefaultCount() const + { + return UserCount() + mDefaultEntries.Count(); + } + uint32_t UserCount() const { return mUserEntries.Length(); } + + // These return the byte sizes of the default and user value arrays, + // respectively. + uint32_t DefaultSize() const { return DefaultCount() * sizeof(ValueType); } + uint32_t UserSize() const { return UserCount() * sizeof(ValueType); } + + void Clear() + { + mUserEntries.Clear(); + mDefaultEntries.Clear(); + } + + static constexpr size_t Alignment() { return alignof(ValueType); } + + private: + struct Entry + { + uint16_t mIndex; + bool mHasUserValue; + ValueType mDefaultValue; + ValueType mUserValue{}; + }; + + AutoTArray mUserEntries; + + nsDataHashtable mDefaultEntries; + }; + + // A special-purpose string table builder for keys which are already + // guaranteed to be unique. Duplicate values will not be detected or + // de-duplicated. + template + class UniqueStringTableBuilder + { + public: + using ElemType = CharType; + + explicit UniqueStringTableBuilder(size_t aCapacity) + : mEntries(aCapacity) + { + } + + StringTableEntry Add(const CharType* aKey) + { + auto entry = + mEntries.AppendElement(Entry{ mSize, uint32_t(strlen(aKey)), aKey }); + + mSize += entry->mLength + 1; + + return { entry->mOffset, entry->mLength }; + } + + void Write(const RangedPtr& aBuffer) + { + auto buffer = aBuffer.ReinterpretCast(); + + for (auto& entry : mEntries) { + memcpy(&buffer[entry.mOffset], + entry.mValue, + sizeof(ElemType) * (entry.mLength + 1)); + } + } + + uint32_t Count() const { return mEntries.Length(); } + + uint32_t Size() const { return mSize * sizeof(ElemType); } + + void Clear() { mEntries.Clear(); } + + static constexpr size_t Alignment() { return alignof(ElemType); } + + private: + struct Entry + { + uint32_t mOffset; + uint32_t mLength; + const CharType* mValue; + }; + + nsTArray mEntries; + uint32_t mSize = 0; + }; + + // A preference value entry, roughly corresponding to the + // SharedPrefMap::Value struct, but with a temporary place-holder value rather + // than a final value index. + union Value { + Value(bool aDefaultValue, bool aUserValue) + : mDefaultBool(aDefaultValue) + , mUserBool(aUserValue) + { + } + + MOZ_IMPLICIT Value(const ValueIdx& aIndex) + : mIndex(aIndex) + { + } + + // For Bool preferences, their default and user bool values. + struct + { + bool mDefaultBool; + bool mUserBool; + }; + // For Int and String preferences, an opaque descriptor for their entries in + // their value arrays. This must be passed to the appropriate + // ValueTableBuilder to obtain the final index when the entry is serialized. + ValueIdx mIndex; + }; + + // A preference entry, to be converted to a SharedPrefMap::Entry struct during + // serialization. + struct Entry + { + // The entry's preference name, as passed to Add(). The caller is + // responsible for keeping this pointer alive until the builder is + // finalized. + const char* mKeyString; + // The entry in mKeyTable corresponding to mKeyString. + StringTableEntry mKey; + Value mValue; + + uint8_t mType : 2; + uint8_t mHasDefaultValue : 1; + uint8_t mHasUserValue : 1; + uint8_t mIsSticky : 1; + uint8_t mIsLocked : 1; + }; + + // Converts a builder Value struct to a SharedPrefMap::Value struct for + // serialization. This must not be called before callers have finished adding + // entries to the value array builders. + SharedPrefMap::Value GetValue(const Entry& aEntry) const + { + switch (PrefType(aEntry.mType)) { + case PrefType::Bool: + return { aEntry.mValue.mDefaultBool, aEntry.mValue.mUserBool }; + case PrefType::Int: + return { mIntValueTable.GetIndex(aEntry.mValue.mIndex) }; + case PrefType::String: + return { mStringValueTable.GetIndex(aEntry.mValue.mIndex) }; + default: + MOZ_ASSERT_UNREACHABLE("Invalid pref type"); + return { false, false }; + } + } + + UniqueStringTableBuilder mKeyTable{ kExpectedPrefCount }; + StringTableBuilder mValueStringTable; + + ValueTableBuilder mIntValueTable; + ValueTableBuilder, StringTableEntry> + mStringValueTable; + + nsTArray mEntries{ kExpectedPrefCount }; +}; + +} // mozilla + +#endif // dom_ipc_SharedPrefMap_h diff --git a/modules/libpref/moz.build b/modules/libpref/moz.build index 9e81d107b3ee..017dd86591c6 100644 --- a/modules/libpref/moz.build +++ b/modules/libpref/moz.build @@ -32,6 +32,7 @@ EXPORTS.mozilla += [ UNIFIED_SOURCES += [ 'Preferences.cpp', + 'SharedPrefMap.cpp', ] include('/ipc/chromium/chromium-config.mozbuild') diff --git a/modules/libpref/nsIPrefService.idl b/modules/libpref/nsIPrefService.idl index b0074b10b47d..3287ff1ec227 100644 --- a/modules/libpref/nsIPrefService.idl +++ b/modules/libpref/nsIPrefService.idl @@ -15,7 +15,7 @@ interface nsIFile; [function, scriptable, uuid(c3f0cedc-e244-4316-b33a-80306a1c35a1)] interface nsIPrefStatsCallback : nsISupports { - void visit(in string prefName, in unsigned long accessCount); + void visit(in ACString prefName, in unsigned long accessCount); }; /** diff --git a/modules/libpref/test/unit/test_libPrefs.js b/modules/libpref/test/unit/test_libPrefs.js index f7bdf6380669..375f11944c90 100644 --- a/modules/libpref/test/unit/test_libPrefs.js +++ b/modules/libpref/test/unit/test_libPrefs.js @@ -235,9 +235,9 @@ function run_test() { // locking and unlocking a nonexistent pref should throw do_check_throws(function() { - ps.lockPref("DefaultPref.nonexistent");}, Cr.NS_ERROR_UNEXPECTED); + ps.lockPref("DefaultPref.nonexistent");}, Cr.NS_ERROR_ILLEGAL_VALUE); do_check_throws(function() { - ps.unlockPref("DefaultPref.nonexistent");}, Cr.NS_ERROR_UNEXPECTED); + ps.unlockPref("DefaultPref.nonexistent");}, Cr.NS_ERROR_ILLEGAL_VALUE); // getting a locked pref branch should return the "default" value Assert.ok(!ps.prefIsLocked("DefaultPref.char")); diff --git a/modules/libpref/test/unit_ipc/test_large_pref.js b/modules/libpref/test/unit_ipc/test_large_pref.js index e4a5430c1218..ac3acffac788 100644 --- a/modules/libpref/test/unit_ipc/test_large_pref.js +++ b/modules/libpref/test/unit_ipc/test_large_pref.js @@ -52,6 +52,14 @@ function run_test() { let isParent = isParentProcess(); if (isParent) { + // Preferences with large values will still appear in the shared memory + // snapshot that we share with all processes. They should not, however, be + // sent with the list of changes on top of the snapshot. + // + // So, make sure we've generated the initial snapshot before we set the + // preference values by launching a child process with an empty test. + sendCommand(""); + // Set all combinations of none, small and large, for default and user prefs. for (let def of testValues) { for (let user of testValues) { @@ -82,8 +90,8 @@ function run_test() { // large, so the preference should not be set. let prefExists; try { - pb.getCharPref(pref_name); - prefExists = true; + let val = pb.getCharPref(pref_name); + prefExists = val.length > 128; } catch(e) { prefExists = false; } diff --git a/modules/libpref/test/unit_ipc/test_sharedMap.js b/modules/libpref/test/unit_ipc/test_sharedMap.js new file mode 100644 index 000000000000..2c4449e7ff67 --- /dev/null +++ b/modules/libpref/test/unit_ipc/test_sharedMap.js @@ -0,0 +1,302 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +"use strict"; + +// This file tests the functionality of the preference service when using a +// shared memory snapshot. In this configuration, a snapshot of the initial +// state of the preferences database is made when we first spawn a child +// process, and changes after that point are stored as entries in a dynamic hash +// table, on top of the snapshot. + +ChromeUtils.import("resource://gre/modules/Services.jsm"); +ChromeUtils.import("resource://testing-common/ExtensionXPCShellUtils.jsm"); + +ExtensionTestUtils.init(this); + +let contentPage; + +const {prefs} = Services; +const defaultPrefs = prefs.getDefaultBranch(""); + +const FRAME_SCRIPT_INIT = ` + ChromeUtils.import("resource://gre/modules/Services.jsm"); + const {prefs} = Services; + const defaultPrefs = prefs.getDefaultBranch(""); +`; + +function try_(fn) { + try { + return fn(); + } catch (e) { + return undefined; + } +} + +function getPref(pref) { + let flags = { + locked: try_(() => prefs.prefIsLocked(pref)), + hasUser: try_(() => prefs.prefHasUserValue(pref)), + }; + + switch (prefs.getPrefType(pref)) { + case prefs.PREF_INT: + return { + ...flags, + type: "Int", + user: try_(() => prefs.getIntPref(pref)), + default: try_(() => defaultPrefs.getIntPref(pref)), + }; + case prefs.PREF_BOOL: + return { + ...flags, + type: "Bool", + user: try_(() => prefs.getBoolPref(pref)), + default: try_(() => defaultPrefs.getBoolPref(pref)), + }; + case prefs.PREF_STRING: + return { + ...flags, + type: "String", + user: try_(() => prefs.getStringPref(pref)), + default: try_(() => defaultPrefs.getStringPref(pref)), + }; + } + return {}; +} + +function getPrefs(prefNames) { + let result = {}; + for (let pref of prefNames) { + result[pref] = getPref(pref); + } + result.childList = prefs.getChildList(""); + return result; +} + +function checkPref(pref, proc, val, type, userVal, defaultVal, expectedFlags = {}) { + info(`Check "${pref}" ${proc} value`); + + equal(val.type, type, `Expected type for "${pref}"`); + equal(val.user, userVal, `Expected user value for "${pref}"`); + + // We only send changes to the content process when they'll make a visible + // difference, so ignore content process default values when we have a defined + // user value. + if (proc !== "content" || val.user === undefined) { + equal(val.default, defaultVal, `Expected default value for "${pref}"`); + } + + for (let [flag, value] of Object.entries(expectedFlags)) { + equal(val[flag], value, `Expected ${flag} value for "${pref}"`); + } +} + +function getPrefList() { + return prefs.getChildList(""); +} + +const TESTS = { + "exists.thenDoesNot": { + beforeContent(PREF) { + prefs.setBoolPref(PREF, true); + + ok(getPrefList().includes(PREF), `Parent list includes "${PREF}"`); + }, + contentStartup(PREF, val, childList) { + ok(getPrefList().includes(PREF), `Parent list includes "${PREF}"`); + ok(childList.includes(PREF), `Child list includes "${PREF}"`); + + prefs.clearUserPref(PREF); + ok(!getPrefList().includes(PREF), `Parent list doesn't include "${PREF}"`); + }, + contentUpdate1(PREF, val, childList) { + ok(!getPrefList().includes(PREF), `Parent list doesn't include "${PREF}"`); + ok(!childList.includes(PREF), `Child list doesn't include "${PREF}"`); + + prefs.setCharPref(PREF, "foo"); + ok(getPrefList().includes(PREF), `Parent list includes "${PREF}"`); + checkPref(PREF, "parent", getPref(PREF), "String", "foo"); + }, + contentUpdate2(PREF, val, childList) { + ok(getPrefList().includes(PREF), `Parent list includes "${PREF}"`); + ok(childList.includes(PREF), `Child list includes "${PREF}"`); + + checkPref(PREF, "parent", getPref(PREF), "String", "foo"); + checkPref(PREF, "child", val, "String", "foo"); + }, + }, + "doesNotExists.thenDoes": { + contentStartup(PREF, val, childList) { + ok(!getPrefList().includes(PREF), `Parent list doesn't include "${PREF}"`); + ok(!childList.includes(PREF), `Child list doesn't include "${PREF}"`); + + prefs.setIntPref(PREF, 42); + ok(getPrefList().includes(PREF), `Parent list includes "${PREF}"`); + }, + contentUpdate1(PREF, val, childList) { + ok(getPrefList().includes(PREF), `Parent list includes "${PREF}"`); + ok(childList.includes(PREF), `Child list includes "${PREF}"`); + + checkPref(PREF, "parent", getPref(PREF), "Int", 42); + checkPref(PREF, "child", val, "Int", 42); + }, + }, +}; + +const PREFS = [ + {type: "Bool", values: [true, false, true]}, + {type: "Int", values: [24, 42, 73]}, + {type: "String", values: ["meh", "hem", "hrm"]}, +]; + +for (let {type, values} of PREFS) { + let set = `set${type}Pref`; + let get = `get${type}Pref`; + + function prefTest(opts) { + function check(pref, proc, val, {expectedVal, defaultVal = undefined, expectedDefault = defaultVal, expectedFlags = {}}) { + checkPref(pref, proc, val, type, expectedVal, expectedDefault, expectedFlags); + } + + function updatePref(PREF, + {userVal = undefined, + defaultVal = undefined, + flags = {}}) { + info(`Update "${PREF}"`); + if (userVal !== undefined) { + prefs[set](PREF, userVal); + } + if (defaultVal !== undefined) { + defaultPrefs[set](PREF, defaultVal); + } + if (flags.locked === true) { + prefs.lockPref(PREF); + } else if (flags.locked === false) { + prefs.unlockPref(PREF); + } + } + + return { + beforeContent(PREF) { + updatePref(PREF, opts.initial) + check(PREF, "parent", getPref(PREF), opts.initial); + }, + contentStartup(PREF, contentVal) { + check(PREF, "content", contentVal, opts.initial); + check(PREF, "parent", getPref(PREF), opts.initial); + + updatePref(PREF, opts.change1) + check(PREF, "parent", getPref(PREF), opts.change1); + }, + contentUpdate1(PREF, contentVal) { + check(PREF, "content", contentVal, opts.change1); + check(PREF, "parent", getPref(PREF), opts.change1); + + if (opts.change2) { + updatePref(PREF, opts.change2) + check(PREF, "parent", getPref(PREF), opts.change2); + } + }, + contentUpdate2(PREF, contentVal) { + if (opts.change2) { + check(PREF, "content", contentVal, opts.change2); + check(PREF, "parent", getPref(PREF), opts.change2); + } + }, + }; + } + + for (let i of [0, 1]) { + let userVal = values[i]; + let defaultVal = values[+!i]; + + TESTS[`type.${type}.${i}.default`] = prefTest({ + initial: {defaultVal, expectedVal: defaultVal}, + change1: {defaultVal: values[2], expectedVal: values[2]}, + }); + + TESTS[`type.${type}.${i}.user`] = prefTest({ + initial: {userVal, expectedVal: userVal}, + change1: {defaultVal: values[2], expectedVal: userVal}, + change2: {userVal: values[2], + expectedDefault: values[2], + expectedVal: values[2]}, + }); + + TESTS[`type.${type}.${i}.both`] = prefTest({ + initial: {userVal, defaultVal, expectedVal: userVal}, + change1: {defaultVal: values[2], expectedVal: userVal}, + change2: {userVal: values[2], + expectedDefault: values[2], + expectedVal: values[2]}, + }); + + TESTS[`type.${type}.${i}.both.thenLock`] = prefTest({ + initial: {userVal, defaultVal, expectedVal: userVal}, + change1: {expectedDefault: defaultVal, + expectedVal: defaultVal, + flags: {locked: true}, + expectFlags: {locked: true}}, + }); + + TESTS[`type.${type}.${i}.both.thenUnlock`] = prefTest({ + initial: {userVal, defaultVal, expectedVal: defaultVal, + flags: {locked: true}, expectedFlags: {locked: true}}, + change1: {expectedDefault: defaultVal, + expectedVal: userVal, + flags: {locked: false}, + expectFlags: {locked: false}}, + }); + + TESTS[`type.${type}.${i}.both.locked`] = prefTest({ + initial: {userVal, defaultVal, expectedVal: defaultVal, + flags: {locked: true}, expectedFlags: {locked: true}}, + change1: {userVal: values[2], + expectedDefault: defaultVal, + expectedVal: defaultVal, + expectedFlags: {locked: true}}, + change2: {defaultVal: values[2], + expectedDefault: defaultVal, + expectedVal: defaultVal, + expectedFlags: {locked: true}}, + }); + } +} + +add_task(async function test_sharedMap_prefs() { + let prefValues = {}; + + async function runChecks(op) { + for (let [pref, ops] of Object.entries(TESTS)) { + if (ops[op]) { + info(`Running ${op} for "${pref}"`); + await ops[op](pref, + prefValues[pref] || undefined, + prefValues.childList || undefined); + } + } + } + + await runChecks("beforeContent"); + + contentPage = await ExtensionTestUtils.loadContentPage("about:blank", {remote: true}); + registerCleanupFunction(() => contentPage.close()); + + contentPage.addFrameScriptHelper(FRAME_SCRIPT_INIT); + contentPage.addFrameScriptHelper(try_); + contentPage.addFrameScriptHelper(getPref); + + let prefNames = Object.keys(TESTS); + prefValues = await contentPage.spawn(prefNames, getPrefs); + + await runChecks("contentStartup"); + + prefValues = await contentPage.spawn(prefNames, getPrefs); + + await runChecks("contentUpdate1"); + + prefValues = await contentPage.spawn(prefNames, getPrefs); + + await runChecks("contentUpdate2"); +}); diff --git a/modules/libpref/test/unit_ipc/xpcshell.ini b/modules/libpref/test/unit_ipc/xpcshell.ini index f498a7377dcc..fcac6434bdf6 100644 --- a/modules/libpref/test/unit_ipc/xpcshell.ini +++ b/modules/libpref/test/unit_ipc/xpcshell.ini @@ -8,4 +8,5 @@ skip-if = toolkit == 'android' [test_locked_prefs.js] [test_observed_prefs.js] [test_update_prefs.js] +[test_sharedMap.js] [test_user_default_prefs.js] diff --git a/mozglue/android/APKOpen.cpp b/mozglue/android/APKOpen.cpp index ea86cee29c3b..6d3736a52798 100644 --- a/mozglue/android/APKOpen.cpp +++ b/mozglue/android/APKOpen.cpp @@ -393,7 +393,7 @@ FreeArgv(char** argv, int argc) } extern "C" APKOPEN_EXPORT void MOZ_JNICALL -Java_org_mozilla_gecko_mozglue_GeckoLoader_nativeRun(JNIEnv *jenv, jclass jc, jobjectArray jargs, int prefsFd, int ipcFd, int crashFd, int crashAnnotationFd) +Java_org_mozilla_gecko_mozglue_GeckoLoader_nativeRun(JNIEnv *jenv, jclass jc, jobjectArray jargs, int prefsFd, int prefMapFd, int ipcFd, int crashFd, int crashAnnotationFd) { int argc = 0; char** argv = CreateArgvFromObjectArray(jenv, jargs, &argc); @@ -408,7 +408,7 @@ Java_org_mozilla_gecko_mozglue_GeckoLoader_nativeRun(JNIEnv *jenv, jclass jc, jo gBootstrap->GeckoStart(jenv, argv, argc, sAppData); ElfLoader::Singleton.ExpectShutdown(true); } else { - gBootstrap->XRE_SetAndroidChildFds(jenv, prefsFd, ipcFd, crashFd, crashAnnotationFd); + gBootstrap->XRE_SetAndroidChildFds(jenv, { prefsFd, prefMapFd, ipcFd, crashFd, crashAnnotationFd }); gBootstrap->XRE_SetProcessType(argv[argc - 1]); XREChildData childData; diff --git a/mozglue/misc/PlatformMutex.h b/mozglue/misc/PlatformMutex.h index f587c1e602c3..5989bc2dfa08 100644 --- a/mozglue/misc/PlatformMutex.h +++ b/mozglue/misc/PlatformMutex.h @@ -29,10 +29,6 @@ public: MFBT_API MutexImpl(); MFBT_API ~MutexImpl(); - bool operator==(const MutexImpl& rhs) { - return platformData_ == rhs.platformData_; - } - protected: MFBT_API void lock(); MFBT_API void unlock(); @@ -42,6 +38,7 @@ private: void operator=(const MutexImpl&) = delete; MutexImpl(MutexImpl&&) = delete; void operator=(MutexImpl&&) = delete; + bool operator==(const MutexImpl& rhs) = delete; void mutexLock(); #ifdef XP_DARWIN diff --git a/taskcluster/ci/build/windows.yml b/taskcluster/ci/build/windows.yml index 902028a5205a..b1b12f8b6a35 100755 --- a/taskcluster/ci/build/windows.yml +++ b/taskcluster/ci/build/windows.yml @@ -798,12 +798,12 @@ win32-msvc/debug: - win64-sccache win32-msvc/opt: - description: "Win32 MSVC Opt" + description: "Win32 MSVC PGO" index: product: firefox - job-name: win32-msvc-opt + job-name: win32-msvc-pgo treeherder: - platform: windows2012-32/opt + platform: windows2012-32/pgo symbol: Bmsvc tier: 2 stub-installer: @@ -820,7 +820,7 @@ win32-msvc/opt: PERFHERDER_EXTRA_OPTIONS: msvc run: using: mozharness - options: [append-env-variables-from-configs] + options: [enable-pgo, append-env-variables-from-configs] script: mozharness/scripts/fx_desktop_build.py config: - builds/releng_base_firefox.py @@ -868,12 +868,12 @@ win64-msvc/debug: - win64-sccache win64-msvc/opt: - description: "Win64 MSVC Opt" + description: "Win64 MSVC PGO" index: product: firefox - job-name: win64-msvc-opt + job-name: win64-msvc-pgo treeherder: - platform: windows2012-64/opt + platform: windows2012-64/pgo symbol: Bmsvc tier: 2 worker-type: aws-provisioner-v1/gecko-{level}-b-win2012 @@ -884,7 +884,7 @@ win64-msvc/opt: PERFHERDER_EXTRA_OPTIONS: msvc run: using: mozharness - options: [append-env-variables-from-configs] + options: [enable-pgo, append-env-variables-from-configs] script: mozharness/scripts/fx_desktop_build.py config: - builds/releng_base_firefox.py diff --git a/taskcluster/ci/test/compiled.yml b/taskcluster/ci/test/compiled.yml index 2948ce31dcef..b1f5356ba561 100644 --- a/taskcluster/ci/test/compiled.yml +++ b/taskcluster/ci/test/compiled.yml @@ -40,6 +40,7 @@ gtest: run-on-projects: by-test-platform: windows.*-pgo/.*: [] # permafails on pgo + windows.*-msvc/opt: [] # msvc opt builds are pgo windows.*-nightly/.*: [] # permafails on nightly too windows10-64-asan/opt: [] # permafails on asan too .*-devedition/.*: [] # don't run on devedition diff --git a/toolkit/components/extensions/ExtensionXPCShellUtils.jsm b/toolkit/components/extensions/ExtensionXPCShellUtils.jsm index 6a41b9e0eb45..e47dff0a4ccd 100644 --- a/toolkit/components/extensions/ExtensionXPCShellUtils.jsm +++ b/toolkit/components/extensions/ExtensionXPCShellUtils.jsm @@ -167,6 +167,11 @@ class ContentPage { this.browser.messageManager.loadFrameScript(frameScript, true); } + addFrameScriptHelper(func) { + let frameScript = `data:text/javascript,${encodeURI(func)}`; + this.browser.messageManager.loadFrameScript(frameScript, false, true); + } + async loadURL(url, redirectUrl = undefined) { await this.browserReady; diff --git a/toolkit/components/extensions/test/xpcshell/data/file_shadowdom.html b/toolkit/components/extensions/test/xpcshell/data/file_shadowdom.html new file mode 100644 index 000000000000..c4e7db14e729 --- /dev/null +++ b/toolkit/components/extensions/test/xpcshell/data/file_shadowdom.html @@ -0,0 +1,13 @@ + + + + + + +
host
+ + + diff --git a/toolkit/components/extensions/test/xpcshell/test_ext_shadowdom.js b/toolkit/components/extensions/test/xpcshell/test_ext_shadowdom.js new file mode 100644 index 000000000000..527be692491d --- /dev/null +++ b/toolkit/components/extensions/test/xpcshell/test_ext_shadowdom.js @@ -0,0 +1,65 @@ +"use strict"; + +ChromeUtils.defineModuleGetter(this, "Preferences", + "resource://gre/modules/Preferences.jsm"); + +// ExtensionContent.jsm needs to know when it's running from xpcshell, +// to use the right timeout for content scripts executed at document_idle. +ExtensionTestUtils.mockAppInfo(); + +const server = createHttpServer(); +server.registerDirectory("/data/", do_get_file("data")); + +const BASE_URL = `http://localhost:${server.identity.primaryPort}/data`; + +add_task(async function test_contentscript_shadowDOM() { + const PREFS = { + "dom.webcomponents.shadowdom.enabled": true, + }; + + // Set prefs to our initial values. + for (let pref in PREFS) { + Preferences.set(pref, PREFS[pref]); + } + + registerCleanupFunction(() => { + // Reset the prefs. + for (let pref in PREFS) { + Preferences.reset(pref); + } + }); + + function backgroundScript() { + browser.test.assertTrue("openOrClosedShadowRoot" in document.documentElement, + "Should have openOrClosedShadowRoot in Element in background script."); + } + + function contentScript() { + let host = document.getElementById("host"); + browser.test.assertTrue("openOrClosedShadowRoot" in host, "Should have openOrClosedShadowRoot in Element."); + let shadowRoot = host.openOrClosedShadowRoot; + browser.test.assertEq(shadowRoot.mode, "closed", "Should have closed ShadowRoot."); + browser.test.sendMessage("contentScript"); + } + + let extension = ExtensionTestUtils.loadExtension({ + manifest: { + content_scripts: [{ + "matches": ["http://*/*/file_shadowdom.html"], + "js": ["content_script.js"], + }], + }, + background: backgroundScript, + files: { + "content_script.js": contentScript, + }, + }); + + await extension.startup(); + + let contentPage = await ExtensionTestUtils.loadContentPage(`${BASE_URL}/file_shadowdom.html`); + await extension.awaitMessage("contentScript"); + + await contentPage.close(); + await extension.unload(); +}); diff --git a/toolkit/components/extensions/test/xpcshell/xpcshell-content.ini b/toolkit/components/extensions/test/xpcshell/xpcshell-content.ini index f092113cad9e..7b0b6668b88f 100644 --- a/toolkit/components/extensions/test/xpcshell/xpcshell-content.ini +++ b/toolkit/components/extensions/test/xpcshell/xpcshell-content.ini @@ -10,3 +10,4 @@ skip-if = (os == "android" && debug) || (os == "win" && debug) # Windows: Bug 14 [test_ext_contentScripts_register.js] skip-if = os == "android" [test_ext_adoption_with_xrays.js] +[test_ext_shadowdom.js] diff --git a/toolkit/components/tooltiptext/TooltipTextProvider.js b/toolkit/components/tooltiptext/TooltipTextProvider.js index 7b388281022a..60112257678f 100644 --- a/toolkit/components/tooltiptext/TooltipTextProvider.js +++ b/toolkit/components/tooltiptext/TooltipTextProvider.js @@ -9,11 +9,10 @@ function TooltipTextProvider() {} TooltipTextProvider.prototype = { getNodeText(tipElement, textOut, directionOut) { - // Don't show the tooltip if the tooltip node is a document, browser, or disconnected. + // Don't show the tooltip if the tooltip node is a document or browser. + // Caller should ensure the node is in (composed) document. if (!tipElement || !tipElement.ownerDocument || - tipElement.localName == "browser" || - (tipElement.ownerDocument.compareDocumentPosition(tipElement) & - tipElement.ownerDocument.DOCUMENT_POSITION_DISCONNECTED)) { + tipElement.localName == "browser") { return false; } @@ -123,7 +122,18 @@ TooltipTextProvider.prototype = { usedTipElement = tipElement; } - tipElement = tipElement.parentNode; + let parent = tipElement.parentNode; + if (defView.ShadowRoot && + parent instanceof defView.ShadowRoot) { + tipElement = parent.host; + } else { + let slot = tipElement.openOrClosedAssignedSlot; + if (slot) { + tipElement = slot; + } else { + tipElement = parent; + } + } } return [titleText, XLinkTitleText, SVGTitleText, XULtooltiptextText].some(function(t) { diff --git a/toolkit/components/tooltiptext/tests/browser.ini b/toolkit/components/tooltiptext/tests/browser.ini index 3f07bb26a183..2c2fcea29c7a 100644 --- a/toolkit/components/tooltiptext/tests/browser.ini +++ b/toolkit/components/tooltiptext/tests/browser.ini @@ -6,3 +6,4 @@ support-files = xul_tooltiptext.xhtml [browser_bug581947.js] [browser_input_file_tooltips.js] skip-if = os == 'win' && os_version == '10.0' # Permafail on Win 10 (bug 1400368) +[browser_shadow_dom_tooltip.js] diff --git a/toolkit/components/tooltiptext/tests/browser_shadow_dom_tooltip.js b/toolkit/components/tooltiptext/tests/browser_shadow_dom_tooltip.js new file mode 100644 index 000000000000..cc5a8431be05 --- /dev/null +++ b/toolkit/components/tooltiptext/tests/browser_shadow_dom_tooltip.js @@ -0,0 +1,131 @@ +/* eslint-disable mozilla/no-arbitrary-setTimeout */ + +add_task(async function setup() { + await SpecialPowers.pushPrefEnv( + {"set": [["ui.tooltipDelay", 0], + ["dom.webcomponents.shadowdom.enabled", true]]}); +}); + +add_task(async function test_title_in_shadow_dom() { + let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser); + + info("Moving mouse out of the way."); + await EventUtils.synthesizeAndWaitNativeMouseMove(tab.linkedBrowser, 300, 300); + + info("creating host"); + await ContentTask.spawn(tab.linkedBrowser, {}, async function() { + let doc = content.document; + let host = doc.createElement("div"); + doc.body.appendChild(host); + host.setAttribute("style", "position: absolute; top: 0; left: 0;"); + var sr = host.attachShadow({ mode: "closed" }); + sr.innerHTML = "
shadow
"; + }); + + let awaitTooltipOpen = new Promise(resolve => { + let tooltipId = Services.appinfo.browserTabsRemoteAutostart ? + "remoteBrowserTooltip" : + "aHTMLTooltip"; + let tooltip = document.getElementById(tooltipId); + tooltip.addEventListener("popupshown", function(event) { + resolve(event.target); + }, {once: true}); + }); + info("Initial mouse move"); + await EventUtils.synthesizeAndWaitNativeMouseMove(tab.linkedBrowser, 50, 5); + info("Waiting"); + await new Promise(resolve => setTimeout(resolve, 400)); + info("Second mouse move"); + await EventUtils.synthesizeAndWaitNativeMouseMove(tab.linkedBrowser, 70, 5); + info("Waiting for tooltip to open"); + let tooltip = await awaitTooltipOpen; + + is(tooltip.getAttribute("label"), "shadow", "tooltip label should match expectation"); + + info("Closing tab"); + BrowserTestUtils.removeTab(tab); +}); + +add_task(async function test_title_in_light_dom() { + let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser); + + info("Moving mouse out of the way."); + await EventUtils.synthesizeAndWaitNativeMouseMove(tab.linkedBrowser, 300, 300); + + info("creating host"); + await ContentTask.spawn(tab.linkedBrowser, {}, async function() { + let doc = content.document; + let host = doc.createElement("div"); + host.title = "light"; + doc.body.appendChild(host); + host.setAttribute("style", "position: absolute; top: 0; left: 0;"); + var sr = host.attachShadow({ mode: "closed" }); + sr.innerHTML = "
shadow
"; + }); + + let awaitTooltipOpen = new Promise(resolve => { + let tooltipId = Services.appinfo.browserTabsRemoteAutostart ? + "remoteBrowserTooltip" : + "aHTMLTooltip"; + let tooltip = document.getElementById(tooltipId); + tooltip.addEventListener("popupshown", function(event) { + resolve(event.target); + }, {once: true}); + }); + info("Initial mouse move"); + await EventUtils.synthesizeAndWaitNativeMouseMove(tab.linkedBrowser, 50, 5); + info("Waiting"); + await new Promise(resolve => setTimeout(resolve, 400)); + info("Second mouse move"); + await EventUtils.synthesizeAndWaitNativeMouseMove(tab.linkedBrowser, 70, 5); + info("Waiting for tooltip to open"); + let tooltip = await awaitTooltipOpen; + + is(tooltip.getAttribute("label"), "light", "tooltip label should match expectation"); + + info("Closing tab"); + BrowserTestUtils.removeTab(tab); +}); + + +add_task(async function test_title_through_slot() { + let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser); + + info("Moving mouse out of the way."); + await EventUtils.synthesizeAndWaitNativeMouseMove(tab.linkedBrowser, 300, 300); + + info("creating host"); + await ContentTask.spawn(tab.linkedBrowser, {}, async function() { + let doc = content.document; + let host = doc.createElement("div"); + host.title = "light"; + host.innerHTML = "
light
"; + doc.body.appendChild(host); + host.setAttribute("style", "position: absolute; top: 0; left: 0;"); + var sr = host.attachShadow({ mode: "closed" }); + sr.innerHTML = "
"; + }); + + let awaitTooltipOpen = new Promise(resolve => { + let tooltipId = Services.appinfo.browserTabsRemoteAutostart ? + "remoteBrowserTooltip" : + "aHTMLTooltip"; + let tooltip = document.getElementById(tooltipId); + tooltip.addEventListener("popupshown", function(event) { + resolve(event.target); + }, {once: true}); + }); + info("Initial mouse move"); + await EventUtils.synthesizeAndWaitNativeMouseMove(tab.linkedBrowser, 50, 5); + info("Waiting"); + await new Promise(resolve => setTimeout(resolve, 400)); + info("Second mouse move"); + await EventUtils.synthesizeAndWaitNativeMouseMove(tab.linkedBrowser, 70, 5); + info("Waiting for tooltip to open"); + let tooltip = await awaitTooltipOpen; + + is(tooltip.getAttribute("label"), "shadow", "tooltip label should match expectation"); + + info("Closing tab"); + BrowserTestUtils.removeTab(tab); +}); diff --git a/toolkit/xre/Bootstrap.cpp b/toolkit/xre/Bootstrap.cpp index 7e857969a4fb..a4d4843f54f1 100644 --- a/toolkit/xre/Bootstrap.cpp +++ b/toolkit/xre/Bootstrap.cpp @@ -78,8 +78,8 @@ public: ::GeckoStart(aEnv, argv, argc, aAppData); } - virtual void XRE_SetAndroidChildFds(JNIEnv* aEnv, int aPrefsFd, int aIPCFd, int aCrashFd, int aCrashAnnotationFd) override { - ::XRE_SetAndroidChildFds(aEnv, aPrefsFd, aIPCFd, aCrashFd, aCrashAnnotationFd); + virtual void XRE_SetAndroidChildFds(JNIEnv* aEnv, const XRE_AndroidChildFds& aFds) override { + ::XRE_SetAndroidChildFds(aEnv, aFds); } #endif diff --git a/toolkit/xre/Bootstrap.h b/toolkit/xre/Bootstrap.h index 77adcef80e1f..0a03eb2da597 100644 --- a/toolkit/xre/Bootstrap.h +++ b/toolkit/xre/Bootstrap.h @@ -113,7 +113,7 @@ public: #ifdef MOZ_WIDGET_ANDROID virtual void GeckoStart(JNIEnv* aEnv, char** argv, int argc, const StaticXREAppData& aAppData) = 0; - virtual void XRE_SetAndroidChildFds(JNIEnv* aEnv, int aPrefsFd, int aIPCFd, int aCrashFd, int aCrashAnnotationFd) = 0; + virtual void XRE_SetAndroidChildFds(JNIEnv* aEnv, const XRE_AndroidChildFds& fds) = 0; #endif #ifdef LIBFUZZER diff --git a/toolkit/xre/nsEmbedFunctions.cpp b/toolkit/xre/nsEmbedFunctions.cpp index b3322e2b8705..fa6bfdc136b5 100644 --- a/toolkit/xre/nsEmbedFunctions.cpp +++ b/toolkit/xre/nsEmbedFunctions.cpp @@ -244,13 +244,14 @@ GeckoProcessType sChildProcessType = GeckoProcessType_Default; #if defined(MOZ_WIDGET_ANDROID) void -XRE_SetAndroidChildFds (JNIEnv* env, int prefsFd, int ipcFd, int crashFd, int crashAnnotationFd) +XRE_SetAndroidChildFds (JNIEnv* env, const XRE_AndroidChildFds& fds) { mozilla::jni::SetGeckoThreadEnv(env); - mozilla::dom::SetPrefsFd(prefsFd); - IPC::Channel::SetClientChannelFd(ipcFd); - CrashReporter::SetNotificationPipeForChild(crashFd); - CrashReporter::SetCrashAnnotationPipeForChild(crashAnnotationFd); + mozilla::dom::SetPrefsFd(fds.mPrefsFd); + mozilla::dom::SetPrefMapFd(fds.mPrefMapFd); + IPC::Channel::SetClientChannelFd(fds.mIpcFd); + CrashReporter::SetNotificationPipeForChild(fds.mCrashFd); + CrashReporter::SetCrashAnnotationPipeForChild(fds.mCrashAnnotationFd); } #endif // defined(MOZ_WIDGET_ANDROID) diff --git a/uriloader/prefetch/OfflineCacheUpdateChild.cpp b/uriloader/prefetch/OfflineCacheUpdateChild.cpp index 528fabbaf206..70de11cd256a 100644 --- a/uriloader/prefetch/OfflineCacheUpdateChild.cpp +++ b/uriloader/prefetch/OfflineCacheUpdateChild.cpp @@ -7,6 +7,7 @@ #include "OfflineCacheUpdateChild.h" #include "nsOfflineCacheUpdate.h" #include "mozilla/dom/ContentChild.h" +#include "mozilla/dom/OfflineResourceListBinding.h" #include "mozilla/dom/TabChild.h" #include "mozilla/ipc/URIUtils.h" #include "mozilla/net/NeckoCommon.h" @@ -18,7 +19,6 @@ #include "nsIDocShellTreeItem.h" #include "nsIDocShellTreeOwner.h" #include "nsPIDOMWindow.h" -#include "nsIDOMOfflineResourceList.h" #include "nsIDocument.h" #include "nsIObserverService.h" #include "nsIURL.h" @@ -256,13 +256,13 @@ OfflineCacheUpdateChild::GetStatus(uint16_t *aStatus) { switch (mState) { case STATE_CHECKING : - *aStatus = nsIDOMOfflineResourceList::CHECKING; + *aStatus = mozilla::dom::OfflineResourceList_Binding::CHECKING; return NS_OK; case STATE_DOWNLOADING : - *aStatus = nsIDOMOfflineResourceList::DOWNLOADING; + *aStatus = mozilla::dom::OfflineResourceList_Binding::DOWNLOADING; return NS_OK; default : - *aStatus = nsIDOMOfflineResourceList::IDLE; + *aStatus = mozilla::dom::OfflineResourceList_Binding::IDLE; return NS_OK; } diff --git a/uriloader/prefetch/nsIOfflineCacheUpdate.idl b/uriloader/prefetch/nsIOfflineCacheUpdate.idl index deafb55a7a14..0617fc34e980 100644 --- a/uriloader/prefetch/nsIOfflineCacheUpdate.idl +++ b/uriloader/prefetch/nsIOfflineCacheUpdate.idl @@ -61,7 +61,7 @@ interface nsIOfflineCacheUpdateObserver : nsISupports { interface nsIOfflineCacheUpdate : nsISupports { /** * Fetch the status of the running update. This will return a value - * defined in nsIDOMOfflineResourceList. + * defined in OfflineResourceList.webidl. */ readonly attribute unsigned short status; diff --git a/uriloader/prefetch/nsOfflineCacheUpdate.cpp b/uriloader/prefetch/nsOfflineCacheUpdate.cpp index addc1877e404..a2171ef511de 100644 --- a/uriloader/prefetch/nsOfflineCacheUpdate.cpp +++ b/uriloader/prefetch/nsOfflineCacheUpdate.cpp @@ -13,9 +13,9 @@ #include "nsICachingChannel.h" #include "nsIContent.h" #include "mozilla/dom/Element.h" +#include "mozilla/dom/OfflineResourceListBinding.h" #include "nsIDocumentLoader.h" #include "nsIDOMWindow.h" -#include "nsIDOMOfflineResourceList.h" #include "nsIDocument.h" #include "nsIObserverService.h" #include "nsIURL.h" @@ -2285,13 +2285,13 @@ nsOfflineCacheUpdate::GetStatus(uint16_t *aStatus) { switch (mState) { case STATE_CHECKING : - *aStatus = nsIDOMOfflineResourceList::CHECKING; + *aStatus = dom::OfflineResourceList_Binding::CHECKING; return NS_OK; case STATE_DOWNLOADING : - *aStatus = nsIDOMOfflineResourceList::DOWNLOADING; + *aStatus = dom::OfflineResourceList_Binding::DOWNLOADING; return NS_OK; default : - *aStatus = nsIDOMOfflineResourceList::IDLE; + *aStatus = dom::OfflineResourceList_Binding::IDLE; return NS_OK; } diff --git a/uriloader/prefetch/nsOfflineCacheUpdateService.cpp b/uriloader/prefetch/nsOfflineCacheUpdateService.cpp index 7552a9a3c4ef..2727527f2e4d 100644 --- a/uriloader/prefetch/nsOfflineCacheUpdateService.cpp +++ b/uriloader/prefetch/nsOfflineCacheUpdateService.cpp @@ -19,7 +19,6 @@ #include "nsIDocShell.h" #include "nsIDocumentLoader.h" #include "nsIDOMWindow.h" -#include "nsIDOMOfflineResourceList.h" #include "nsIDocument.h" #include "nsIObserverService.h" #include "nsIURL.h" @@ -503,11 +502,10 @@ nsOfflineCacheUpdateService::Schedule(nsIURI *aManifestURI, nsresult rv; if (aWindow) { - // Ensure there is window.applicationCache object that is - // responsible for association of the new applicationCache - // with the corresponding document. Just ignore the result. - nsCOMPtr appCacheWindowObject = - aWindow->GetApplicationCache(); + // Ensure there is window.applicationCache object that is + // responsible for association of the new applicationCache + // with the corresponding document. Just ignore the result. + aWindow->GetApplicationCache(); } rv = update->Init(aManifestURI, aDocumentURI, aLoadingPrincipal, aDocument, diff --git a/xpcom/build/nsXULAppAPI.h b/xpcom/build/nsXULAppAPI.h index 110bba3f3f31..1736999571ae 100644 --- a/xpcom/build/nsXULAppAPI.h +++ b/xpcom/build/nsXULAppAPI.h @@ -397,8 +397,17 @@ XRE_API(const char*, XRE_ChildProcessTypeToString, (GeckoProcessType aProcessType)) #if defined(MOZ_WIDGET_ANDROID) +struct XRE_AndroidChildFds +{ + int mPrefsFd; + int mPrefMapFd; + int mIpcFd; + int mCrashFd; + int mCrashAnnotationFd; +}; + XRE_API(void, - XRE_SetAndroidChildFds, (JNIEnv* env, int prefsFd, int ipcFd, int crashFd, int crashAnnotationFd)) + XRE_SetAndroidChildFds, (JNIEnv* env, const XRE_AndroidChildFds& fds)) #endif // defined(MOZ_WIDGET_ANDROID) XRE_API(void,