{ "version": 3, "sources": ["../assets/node_modules/dayjs/dayjs.min.js", "../assets/node_modules/dayjs/plugin/relativeTime.js", "../assets/node_modules/dayjs/plugin/customParseFormat.js", "../assets/node_modules/sprintf-js/src/sprintf.js", "../assets/app.ts", "../assets/node_modules/notyf/notyf.es.js", "../assets/toast.ts", "../assets/node_modules/js-cookie/dist/js.cookie.mjs", "../assets/node_modules/query-string/base.js", "../assets/node_modules/decode-uri-component/index.js", "../assets/node_modules/filter-obj/index.js", "../assets/node_modules/split-on-first/index.js", "../assets/node_modules/query-string/index.js", "../assets/api/client.ts", "../assets/api/contest.ts", "../assets/util.ts", "../assets/node_modules/js-base64/base64.mjs", "../assets/translation.ts", "../assets/_translations.json", "../assets/api/progressCall.ts", "../assets/node_modules/preact/src/constants.js", "../assets/node_modules/preact/src/util.js", "../assets/node_modules/preact/src/options.js", "../assets/node_modules/preact/src/create-element.js", "../assets/node_modules/preact/src/component.js", "../assets/node_modules/preact/src/diff/props.js", "../assets/node_modules/preact/src/create-context.js", "../assets/node_modules/preact/src/diff/children.js", "../assets/node_modules/preact/src/diff/index.js", "../assets/node_modules/preact/src/render.js", "../assets/node_modules/preact/src/clone-element.js", "../assets/node_modules/preact/src/diff/catch-error.js", "../assets/node_modules/preact/devtools/src/devtools.js", "../assets/node_modules/preact/devtools/src/index.js", "../assets/node_modules/preact/debug/src/check-props.js", "../assets/node_modules/preact/debug/src/component-stack.js", "../assets/node_modules/preact/debug/src/debug.js", "../assets/node_modules/preact/debug/src/constants.js", "../assets/node_modules/preact/debug/src/util.js", "../assets/node_modules/preact/debug/src/index.js", "../assets/node_modules/preact-custom-element/src/index.js", "../assets/node_modules/preact/hooks/src/index.js", "../assets/node_modules/preact/jsx-runtime/src/utils.js", "../assets/node_modules/preact/src/constants.js", "../assets/node_modules/preact/jsx-runtime/src/index.js", "../assets/components/common.tsx", "../assets/langs.ts", "../assets/components/sub_mgr.tsx", "../assets/components/users.tsx", "../assets/components/subs_view.tsx", "../assets/components/modal.tsx", "../assets/components/maxscore_breakdown.tsx", "../assets/time.ts", "../assets/components/contest.tsx", "../assets/components/att_renamer.tsx", "../assets/components/tags.tsx", "../assets/components/problem_search.tsx", "../assets/components/glossary.tsx", "../assets/session.ts", "../assets/navbar.ts", "../assets/checkbox_mgr.ts", "../assets/cdn_mgr.ts", "../assets/node_modules/lodash-es/isObject.js", "../assets/node_modules/lodash-es/_freeGlobal.js", "../assets/node_modules/lodash-es/_root.js", "../assets/node_modules/lodash-es/now.js", "../assets/node_modules/lodash-es/_trimmedEndIndex.js", "../assets/node_modules/lodash-es/_baseTrim.js", "../assets/node_modules/lodash-es/_Symbol.js", "../assets/node_modules/lodash-es/_getRawTag.js", "../assets/node_modules/lodash-es/_objectToString.js", "../assets/node_modules/lodash-es/_baseGetTag.js", "../assets/node_modules/lodash-es/isObjectLike.js", "../assets/node_modules/lodash-es/isSymbol.js", "../assets/node_modules/lodash-es/toNumber.js", "../assets/node_modules/lodash-es/debounce.js", "../assets/sub_waiter.ts"], "sourcesContent": ["!function(t,e){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=e():\"function\"==typeof define&&define.amd?define(e):(t=\"undefined\"!=typeof globalThis?globalThis:t||self).dayjs=e()}(this,(function(){\"use strict\";var t=1e3,e=6e4,n=36e5,r=\"millisecond\",i=\"second\",s=\"minute\",u=\"hour\",a=\"day\",o=\"week\",c=\"month\",f=\"quarter\",h=\"year\",d=\"date\",l=\"Invalid Date\",$=/^(\\d{4})[-/]?(\\d{1,2})?[-/]?(\\d{0,2})[Tt\\s]*(\\d{1,2})?:?(\\d{1,2})?:?(\\d{1,2})?[.:]?(\\d+)?$/,y=/\\[([^\\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,M={name:\"en\",weekdays:\"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday\".split(\"_\"),months:\"January_February_March_April_May_June_July_August_September_October_November_December\".split(\"_\"),ordinal:function(t){var e=[\"th\",\"st\",\"nd\",\"rd\"],n=t%100;return\"[\"+t+(e[(n-20)%10]||e[n]||e[0])+\"]\"}},m=function(t,e,n){var r=String(t);return!r||r.length>=e?t:\"\"+Array(e+1-r.length).join(n)+t},v={s:m,z:function(t){var e=-t.utcOffset(),n=Math.abs(e),r=Math.floor(n/60),i=n%60;return(e<=0?\"+\":\"-\")+m(r,2,\"0\")+\":\"+m(i,2,\"0\")},m:function t(e,n){if(e.date()1)return t(u[0])}else{var a=e.name;D[a]=e,i=a}return!r&&i&&(g=i),i||!r&&g},O=function(t,e){if(S(t))return t.clone();var n=\"object\"==typeof e?e:{};return n.date=t,n.args=arguments,new _(n)},b=v;b.l=w,b.i=S,b.w=function(t,e){return O(t,{locale:e.$L,utc:e.$u,x:e.$x,$offset:e.$offset})};var _=function(){function M(t){this.$L=w(t.locale,null,!0),this.parse(t),this.$x=this.$x||t.x||{},this[p]=!0}var m=M.prototype;return m.parse=function(t){this.$d=function(t){var e=t.date,n=t.utc;if(null===e)return new Date(NaN);if(b.u(e))return new Date;if(e instanceof Date)return new Date(e);if(\"string\"==typeof e&&!/Z$/i.test(e)){var r=e.match($);if(r){var i=r[2]-1||0,s=(r[7]||\"0\").substring(0,3);return n?new Date(Date.UTC(r[1],i,r[3]||1,r[4]||0,r[5]||0,r[6]||0,s)):new Date(r[1],i,r[3]||1,r[4]||0,r[5]||0,r[6]||0,s)}}return new Date(e)}(t),this.init()},m.init=function(){var t=this.$d;this.$y=t.getFullYear(),this.$M=t.getMonth(),this.$D=t.getDate(),this.$W=t.getDay(),this.$H=t.getHours(),this.$m=t.getMinutes(),this.$s=t.getSeconds(),this.$ms=t.getMilliseconds()},m.$utils=function(){return b},m.isValid=function(){return!(this.$d.toString()===l)},m.isSame=function(t,e){var n=O(t);return this.startOf(e)<=n&&n<=this.endOf(e)},m.isAfter=function(t,e){return O(t)0,p<=y.r||!y.r){p<=1&&c>0&&(y=h[c-1]);var v=l[y.l];u&&(p=u(\"\"+p)),a=\"string\"==typeof v?v.replace(\"%d\",p):v(p,n,y.l,s);break}}if(n)return a;var M=s?l.future:l.past;return\"function\"==typeof M?M(a):M.replace(\"%s\",a)},n.to=function(r,e){return i(r,e,this,!0)},n.from=function(r,e){return i(r,e,this)};var d=function(r){return r.$u?t.utc():t()};n.toNow=function(r){return this.to(d(this),r)},n.fromNow=function(r){return this.from(d(this),r)}}}));", "!function(e,t){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=t():\"function\"==typeof define&&define.amd?define(t):(e=\"undefined\"!=typeof globalThis?globalThis:e||self).dayjs_plugin_customParseFormat=t()}(this,(function(){\"use strict\";var e={LTS:\"h:mm:ss A\",LT:\"h:mm A\",L:\"MM/DD/YYYY\",LL:\"MMMM D, YYYY\",LLL:\"MMMM D, YYYY h:mm A\",LLLL:\"dddd, MMMM D, YYYY h:mm A\"},t=/(\\[[^[]*\\])|([-_:/.,()\\s]+)|(A|a|Q|YYYY|YY?|ww?|MM?M?M?|Do|DD?|hh?|HH?|mm?|ss?|S{1,3}|z|ZZ?)/g,n=/\\d/,r=/\\d\\d/,i=/\\d\\d?/,o=/\\d*[^-_:/,()\\s\\d]+/,s={},a=function(e){return(e=+e)+(e>68?1900:2e3)};var f=function(e){return function(t){this[e]=+t}},h=[/[+-]\\d\\d:?(\\d\\d)?|Z/,function(e){(this.zone||(this.zone={})).offset=function(e){if(!e)return 0;if(\"Z\"===e)return 0;var t=e.match(/([+-]|\\d\\d)/g),n=60*t[1]+(+t[2]||0);return 0===n?0:\"+\"===t[0]?-n:n}(e)}],u=function(e){var t=s[e];return t&&(t.indexOf?t:t.s.concat(t.f))},d=function(e,t){var n,r=s.meridiem;if(r){for(var i=1;i<=24;i+=1)if(e.indexOf(r(i,0,t))>-1){n=i>12;break}}else n=e===(t?\"pm\":\"PM\");return n},c={A:[o,function(e){this.afternoon=d(e,!1)}],a:[o,function(e){this.afternoon=d(e,!0)}],Q:[n,function(e){this.month=3*(e-1)+1}],S:[n,function(e){this.milliseconds=100*+e}],SS:[r,function(e){this.milliseconds=10*+e}],SSS:[/\\d{3}/,function(e){this.milliseconds=+e}],s:[i,f(\"seconds\")],ss:[i,f(\"seconds\")],m:[i,f(\"minutes\")],mm:[i,f(\"minutes\")],H:[i,f(\"hours\")],h:[i,f(\"hours\")],HH:[i,f(\"hours\")],hh:[i,f(\"hours\")],D:[i,f(\"day\")],DD:[r,f(\"day\")],Do:[o,function(e){var t=s.ordinal,n=e.match(/\\d+/);if(this.day=n[0],t)for(var r=1;r<=31;r+=1)t(r).replace(/\\[|\\]/g,\"\")===e&&(this.day=r)}],w:[i,f(\"week\")],ww:[r,f(\"week\")],M:[i,f(\"month\")],MM:[r,f(\"month\")],MMM:[o,function(e){var t=u(\"months\"),n=(u(\"monthsShort\")||t.map((function(e){return e.slice(0,3)}))).indexOf(e)+1;if(n<1)throw new Error;this.month=n%12||n}],MMMM:[o,function(e){var t=u(\"months\").indexOf(e)+1;if(t<1)throw new Error;this.month=t%12||t}],Y:[/[+-]?\\d+/,f(\"year\")],YY:[r,function(e){this.year=a(e)}],YYYY:[/\\d{4}/,f(\"year\")],Z:h,ZZ:h};function l(n){var r,i;r=n,i=s&&s.formats;for(var o=(n=r.replace(/(\\[[^\\]]+])|(LTS?|l{1,4}|L{1,4})/g,(function(t,n,r){var o=r&&r.toUpperCase();return n||i[r]||e[r]||i[o].replace(/(\\[[^\\]]+])|(MMMM|MM|DD|dddd)/g,(function(e,t,n){return t||n.slice(1)}))}))).match(t),a=o.length,f=0;f-1)return new Date((\"X\"===t?1e3:1)*e);var i=l(t)(e),o=i.year,s=i.month,a=i.day,f=i.hours,h=i.minutes,u=i.seconds,d=i.milliseconds,c=i.zone,m=i.week,M=new Date,Y=a||(o||s?1:M.getDate()),p=o||M.getFullYear(),v=0;o&&!s||(v=s>0?s-1:M.getMonth());var D,w=f||0,g=h||0,y=u||0,L=d||0;return c?new Date(Date.UTC(p,v,Y,w,g,y,L+60*c.offset*1e3)):n?new Date(Date.UTC(p,v,Y,w,g,y,L)):(D=new Date(p,v,Y,w,g,y,L),m&&(D=r(D).week(m).toDate()),D)}catch(e){return new Date(\"\")}}(t,a,r,n),this.init(),d&&!0!==d&&(this.$L=this.locale(d).$L),u&&t!=this.format(a)&&(this.$d=new Date(\"\")),s={}}else if(a instanceof Array)for(var c=a.length,m=1;m<=c;m+=1){o[1]=a[m-1];var M=n.apply(this,o);if(M.isValid()){this.$d=M.$d,this.$L=M.$L,this.init();break}m===c&&(this.$d=new Date(\"\"))}else i.call(this,e)}}}));", "/* global window, exports, define */\n\n!function() {\n 'use strict'\n\n var re = {\n not_string: /[^s]/,\n not_bool: /[^t]/,\n not_type: /[^T]/,\n not_primitive: /[^v]/,\n number: /[diefg]/,\n numeric_arg: /[bcdiefguxX]/,\n json: /[j]/,\n not_json: /[^j]/,\n text: /^[^\\x25]+/,\n modulo: /^\\x25{2}/,\n placeholder: /^\\x25(?:([1-9]\\d*)\\$|\\(([^)]+)\\))?(\\+)?(0|'[^$])?(-)?(\\d+)?(?:\\.(\\d+))?([b-gijostTuvxX])/,\n key: /^([a-z_][a-z_\\d]*)/i,\n key_access: /^\\.([a-z_][a-z_\\d]*)/i,\n index_access: /^\\[(\\d+)\\]/,\n sign: /^[+-]/\n }\n\n function sprintf(key) {\n // `arguments` is not an array, but should be fine for this call\n return sprintf_format(sprintf_parse(key), arguments)\n }\n\n function vsprintf(fmt, argv) {\n return sprintf.apply(null, [fmt].concat(argv || []))\n }\n\n function sprintf_format(parse_tree, argv) {\n var cursor = 1, tree_length = parse_tree.length, arg, output = '', i, k, ph, pad, pad_character, pad_length, is_positive, sign\n for (i = 0; i < tree_length; i++) {\n if (typeof parse_tree[i] === 'string') {\n output += parse_tree[i]\n }\n else if (typeof parse_tree[i] === 'object') {\n ph = parse_tree[i] // convenience purposes only\n if (ph.keys) { // keyword argument\n arg = argv[cursor]\n for (k = 0; k < ph.keys.length; k++) {\n if (arg == undefined) {\n throw new Error(sprintf('[sprintf] Cannot access property \"%s\" of undefined value \"%s\"', ph.keys[k], ph.keys[k-1]))\n }\n arg = arg[ph.keys[k]]\n }\n }\n else if (ph.param_no) { // positional argument (explicit)\n arg = argv[ph.param_no]\n }\n else { // positional argument (implicit)\n arg = argv[cursor++]\n }\n\n if (re.not_type.test(ph.type) && re.not_primitive.test(ph.type) && arg instanceof Function) {\n arg = arg()\n }\n\n if (re.numeric_arg.test(ph.type) && (typeof arg !== 'number' && isNaN(arg))) {\n throw new TypeError(sprintf('[sprintf] expecting number but found %T', arg))\n }\n\n if (re.number.test(ph.type)) {\n is_positive = arg >= 0\n }\n\n switch (ph.type) {\n case 'b':\n arg = parseInt(arg, 10).toString(2)\n break\n case 'c':\n arg = String.fromCharCode(parseInt(arg, 10))\n break\n case 'd':\n case 'i':\n arg = parseInt(arg, 10)\n break\n case 'j':\n arg = JSON.stringify(arg, null, ph.width ? parseInt(ph.width) : 0)\n break\n case 'e':\n arg = ph.precision ? parseFloat(arg).toExponential(ph.precision) : parseFloat(arg).toExponential()\n break\n case 'f':\n arg = ph.precision ? parseFloat(arg).toFixed(ph.precision) : parseFloat(arg)\n break\n case 'g':\n arg = ph.precision ? String(Number(arg.toPrecision(ph.precision))) : parseFloat(arg)\n break\n case 'o':\n arg = (parseInt(arg, 10) >>> 0).toString(8)\n break\n case 's':\n arg = String(arg)\n arg = (ph.precision ? arg.substring(0, ph.precision) : arg)\n break\n case 't':\n arg = String(!!arg)\n arg = (ph.precision ? arg.substring(0, ph.precision) : arg)\n break\n case 'T':\n arg = Object.prototype.toString.call(arg).slice(8, -1).toLowerCase()\n arg = (ph.precision ? arg.substring(0, ph.precision) : arg)\n break\n case 'u':\n arg = parseInt(arg, 10) >>> 0\n break\n case 'v':\n arg = arg.valueOf()\n arg = (ph.precision ? arg.substring(0, ph.precision) : arg)\n break\n case 'x':\n arg = (parseInt(arg, 10) >>> 0).toString(16)\n break\n case 'X':\n arg = (parseInt(arg, 10) >>> 0).toString(16).toUpperCase()\n break\n }\n if (re.json.test(ph.type)) {\n output += arg\n }\n else {\n if (re.number.test(ph.type) && (!is_positive || ph.sign)) {\n sign = is_positive ? '+' : '-'\n arg = arg.toString().replace(re.sign, '')\n }\n else {\n sign = ''\n }\n pad_character = ph.pad_char ? ph.pad_char === '0' ? '0' : ph.pad_char.charAt(1) : ' '\n pad_length = ph.width - (sign + arg).length\n pad = ph.width ? (pad_length > 0 ? pad_character.repeat(pad_length) : '') : ''\n output += ph.align ? sign + arg + pad : (pad_character === '0' ? sign + pad + arg : pad + sign + arg)\n }\n }\n }\n return output\n }\n\n var sprintf_cache = Object.create(null)\n\n function sprintf_parse(fmt) {\n if (sprintf_cache[fmt]) {\n return sprintf_cache[fmt]\n }\n\n var _fmt = fmt, match, parse_tree = [], arg_names = 0\n while (_fmt) {\n if ((match = re.text.exec(_fmt)) !== null) {\n parse_tree.push(match[0])\n }\n else if ((match = re.modulo.exec(_fmt)) !== null) {\n parse_tree.push('%')\n }\n else if ((match = re.placeholder.exec(_fmt)) !== null) {\n if (match[2]) {\n arg_names |= 1\n var field_list = [], replacement_field = match[2], field_match = []\n if ((field_match = re.key.exec(replacement_field)) !== null) {\n field_list.push(field_match[1])\n while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {\n if ((field_match = re.key_access.exec(replacement_field)) !== null) {\n field_list.push(field_match[1])\n }\n else if ((field_match = re.index_access.exec(replacement_field)) !== null) {\n field_list.push(field_match[1])\n }\n else {\n throw new SyntaxError('[sprintf] failed to parse named argument key')\n }\n }\n }\n else {\n throw new SyntaxError('[sprintf] failed to parse named argument key')\n }\n match[2] = field_list\n }\n else {\n arg_names |= 2\n }\n if (arg_names === 3) {\n throw new Error('[sprintf] mixing positional and named placeholders is not (yet) supported')\n }\n\n parse_tree.push(\n {\n placeholder: match[0],\n param_no: match[1],\n keys: match[2],\n sign: match[3],\n pad_char: match[4],\n align: match[5],\n width: match[6],\n precision: match[7],\n type: match[8]\n }\n )\n }\n else {\n throw new SyntaxError('[sprintf] unexpected placeholder')\n }\n _fmt = _fmt.substring(match[0].length)\n }\n return sprintf_cache[fmt] = parse_tree\n }\n\n /**\n * export to either browser or node.js\n */\n /* eslint-disable quote-props */\n if (typeof exports !== 'undefined') {\n exports['sprintf'] = sprintf\n exports['vsprintf'] = vsprintf\n }\n if (typeof window !== 'undefined') {\n window['sprintf'] = sprintf\n window['vsprintf'] = vsprintf\n\n if (typeof define === 'function' && define['amd']) {\n define(function() {\n return {\n 'sprintf': sprintf,\n 'vsprintf': vsprintf\n }\n })\n }\n }\n /* eslint-enable quote-props */\n}(); // eslint-disable-line\n", "export * from \"./toast\";\nexport * from \"./api/contest\";\n\n// float-left - leave here to include it in css bundle\n\nexport * from \"./util\";\nexport * from \"./api/client\";\nexport * from \"./api/progressCall\";\nexport * from \"./components\";\n\nexport * from \"./langs\";\nexport { default as getText, maybeGetText } from \"./translation\";\n\nexport * from \"./session\";\nexport { NavBarManager } from \"./navbar\";\nexport { CheckboxManager } from \"./checkbox_mgr\";\nexport { getFileIcon } from \"./cdn_mgr\";\n\nexport { default as debounce } from \"lodash-es/debounce\";\n\nexport { makeSubWaiter } from \"./sub_waiter\";\n\nexport * from \"./time\";\n", "/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n\r\nvar __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n };\r\n return __assign.apply(this, arguments);\r\n};\n\nvar NotyfNotification = /** @class */ (function () {\r\n function NotyfNotification(options) {\r\n this.options = options;\r\n this.listeners = {};\r\n }\r\n NotyfNotification.prototype.on = function (eventType, cb) {\r\n var callbacks = this.listeners[eventType] || [];\r\n this.listeners[eventType] = callbacks.concat([cb]);\r\n };\r\n NotyfNotification.prototype.triggerEvent = function (eventType, event) {\r\n var _this = this;\r\n var callbacks = this.listeners[eventType] || [];\r\n callbacks.forEach(function (cb) { return cb({ target: _this, event: event }); });\r\n };\r\n return NotyfNotification;\r\n}());\r\nvar NotyfArrayEvent;\r\n(function (NotyfArrayEvent) {\r\n NotyfArrayEvent[NotyfArrayEvent[\"Add\"] = 0] = \"Add\";\r\n NotyfArrayEvent[NotyfArrayEvent[\"Remove\"] = 1] = \"Remove\";\r\n})(NotyfArrayEvent || (NotyfArrayEvent = {}));\r\nvar NotyfArray = /** @class */ (function () {\r\n function NotyfArray() {\r\n this.notifications = [];\r\n }\r\n NotyfArray.prototype.push = function (elem) {\r\n this.notifications.push(elem);\r\n this.updateFn(elem, NotyfArrayEvent.Add, this.notifications);\r\n };\r\n NotyfArray.prototype.splice = function (index, num) {\r\n var elem = this.notifications.splice(index, num)[0];\r\n this.updateFn(elem, NotyfArrayEvent.Remove, this.notifications);\r\n return elem;\r\n };\r\n NotyfArray.prototype.indexOf = function (elem) {\r\n return this.notifications.indexOf(elem);\r\n };\r\n NotyfArray.prototype.onUpdate = function (fn) {\r\n this.updateFn = fn;\r\n };\r\n return NotyfArray;\r\n}());\n\nvar NotyfEvent;\r\n(function (NotyfEvent) {\r\n NotyfEvent[\"Dismiss\"] = \"dismiss\";\r\n NotyfEvent[\"Click\"] = \"click\";\r\n})(NotyfEvent || (NotyfEvent = {}));\r\nvar DEFAULT_OPTIONS = {\r\n types: [\r\n {\r\n type: 'success',\r\n className: 'notyf__toast--success',\r\n backgroundColor: '#3dc763',\r\n icon: {\r\n className: 'notyf__icon--success',\r\n tagName: 'i',\r\n },\r\n },\r\n {\r\n type: 'error',\r\n className: 'notyf__toast--error',\r\n backgroundColor: '#ed3d3d',\r\n icon: {\r\n className: 'notyf__icon--error',\r\n tagName: 'i',\r\n },\r\n },\r\n ],\r\n duration: 2000,\r\n ripple: true,\r\n position: {\r\n x: 'right',\r\n y: 'bottom',\r\n },\r\n dismissible: false,\r\n};\n\nvar NotyfView = /** @class */ (function () {\r\n function NotyfView() {\r\n this.notifications = [];\r\n this.events = {};\r\n this.X_POSITION_FLEX_MAP = {\r\n left: 'flex-start',\r\n center: 'center',\r\n right: 'flex-end',\r\n };\r\n this.Y_POSITION_FLEX_MAP = {\r\n top: 'flex-start',\r\n center: 'center',\r\n bottom: 'flex-end',\r\n };\r\n // Creates the main notifications container\r\n var docFrag = document.createDocumentFragment();\r\n var notyfContainer = this._createHTMLElement({ tagName: 'div', className: 'notyf' });\r\n docFrag.appendChild(notyfContainer);\r\n document.body.appendChild(docFrag);\r\n this.container = notyfContainer;\r\n // Identifies the main animation end event\r\n this.animationEndEventName = this._getAnimationEndEventName();\r\n this._createA11yContainer();\r\n }\r\n NotyfView.prototype.on = function (event, cb) {\r\n var _a;\r\n this.events = __assign(__assign({}, this.events), (_a = {}, _a[event] = cb, _a));\r\n };\r\n NotyfView.prototype.update = function (notification, type) {\r\n if (type === NotyfArrayEvent.Add) {\r\n this.addNotification(notification);\r\n }\r\n else if (type === NotyfArrayEvent.Remove) {\r\n this.removeNotification(notification);\r\n }\r\n };\r\n NotyfView.prototype.removeNotification = function (notification) {\r\n var _this = this;\r\n var renderedNotification = this._popRenderedNotification(notification);\r\n var node;\r\n if (!renderedNotification) {\r\n return;\r\n }\r\n node = renderedNotification.node;\r\n node.classList.add('notyf__toast--disappear');\r\n var handleEvent;\r\n node.addEventListener(this.animationEndEventName, (handleEvent = function (event) {\r\n if (event.target === node) {\r\n node.removeEventListener(_this.animationEndEventName, handleEvent);\r\n _this.container.removeChild(node);\r\n }\r\n }));\r\n };\r\n NotyfView.prototype.addNotification = function (notification) {\r\n var node = this._renderNotification(notification);\r\n this.notifications.push({ notification: notification, node: node });\r\n // For a11y purposes, we still want to announce that there's a notification in the screen\r\n // even if it comes with no message.\r\n this._announce(notification.options.message || 'Notification');\r\n };\r\n NotyfView.prototype._renderNotification = function (notification) {\r\n var _a;\r\n var card = this._buildNotificationCard(notification);\r\n var className = notification.options.className;\r\n if (className) {\r\n (_a = card.classList).add.apply(_a, className.split(' '));\r\n }\r\n this.container.appendChild(card);\r\n return card;\r\n };\r\n NotyfView.prototype._popRenderedNotification = function (notification) {\r\n var idx = -1;\r\n for (var i = 0; i < this.notifications.length && idx < 0; i++) {\r\n if (this.notifications[i].notification === notification) {\r\n idx = i;\r\n }\r\n }\r\n if (idx !== -1) {\r\n return this.notifications.splice(idx, 1)[0];\r\n }\r\n return;\r\n };\r\n NotyfView.prototype.getXPosition = function (options) {\r\n var _a;\r\n return ((_a = options === null || options === void 0 ? void 0 : options.position) === null || _a === void 0 ? void 0 : _a.x) || 'right';\r\n };\r\n NotyfView.prototype.getYPosition = function (options) {\r\n var _a;\r\n return ((_a = options === null || options === void 0 ? void 0 : options.position) === null || _a === void 0 ? void 0 : _a.y) || 'bottom';\r\n };\r\n NotyfView.prototype.adjustContainerAlignment = function (options) {\r\n var align = this.X_POSITION_FLEX_MAP[this.getXPosition(options)];\r\n var justify = this.Y_POSITION_FLEX_MAP[this.getYPosition(options)];\r\n var style = this.container.style;\r\n style.setProperty('justify-content', justify);\r\n style.setProperty('align-items', align);\r\n };\r\n NotyfView.prototype._buildNotificationCard = function (notification) {\r\n var _this = this;\r\n var options = notification.options;\r\n var iconOpts = options.icon;\r\n // Adjust container according to position (e.g. top-left, bottom-center, etc)\r\n this.adjustContainerAlignment(options);\r\n // Create elements\r\n var notificationElem = this._createHTMLElement({ tagName: 'div', className: 'notyf__toast' });\r\n var ripple = this._createHTMLElement({ tagName: 'div', className: 'notyf__ripple' });\r\n var wrapper = this._createHTMLElement({ tagName: 'div', className: 'notyf__wrapper' });\r\n var message = this._createHTMLElement({ tagName: 'div', className: 'notyf__message' });\r\n message.innerHTML = options.message || '';\r\n var mainColor = options.background || options.backgroundColor;\r\n // Build the icon and append it to the card\r\n if (iconOpts) {\r\n var iconContainer = this._createHTMLElement({ tagName: 'div', className: 'notyf__icon' });\r\n if (typeof iconOpts === 'string' || iconOpts instanceof String)\r\n iconContainer.innerHTML = new String(iconOpts).valueOf();\r\n if (typeof iconOpts === 'object') {\r\n var _a = iconOpts.tagName, tagName = _a === void 0 ? 'i' : _a, className_1 = iconOpts.className, text = iconOpts.text, _b = iconOpts.color, color = _b === void 0 ? mainColor : _b;\r\n var iconElement = this._createHTMLElement({ tagName: tagName, className: className_1, text: text });\r\n if (color)\r\n iconElement.style.color = color;\r\n iconContainer.appendChild(iconElement);\r\n }\r\n wrapper.appendChild(iconContainer);\r\n }\r\n wrapper.appendChild(message);\r\n notificationElem.appendChild(wrapper);\r\n // Add ripple if applicable, else just paint the full toast\r\n if (mainColor) {\r\n if (options.ripple) {\r\n ripple.style.background = mainColor;\r\n notificationElem.appendChild(ripple);\r\n }\r\n else {\r\n notificationElem.style.background = mainColor;\r\n }\r\n }\r\n // Add dismiss button\r\n if (options.dismissible) {\r\n var dismissWrapper = this._createHTMLElement({ tagName: 'div', className: 'notyf__dismiss' });\r\n var dismissButton = this._createHTMLElement({\r\n tagName: 'button',\r\n className: 'notyf__dismiss-btn',\r\n });\r\n dismissWrapper.appendChild(dismissButton);\r\n wrapper.appendChild(dismissWrapper);\r\n notificationElem.classList.add(\"notyf__toast--dismissible\");\r\n dismissButton.addEventListener('click', function (event) {\r\n var _a, _b;\r\n (_b = (_a = _this.events)[NotyfEvent.Dismiss]) === null || _b === void 0 ? void 0 : _b.call(_a, { target: notification, event: event });\r\n event.stopPropagation();\r\n });\r\n }\r\n notificationElem.addEventListener('click', function (event) { var _a, _b; return (_b = (_a = _this.events)[NotyfEvent.Click]) === null || _b === void 0 ? void 0 : _b.call(_a, { target: notification, event: event }); });\r\n // Adjust margins depending on whether its an upper or lower notification\r\n var className = this.getYPosition(options) === 'top' ? 'upper' : 'lower';\r\n notificationElem.classList.add(\"notyf__toast--\" + className);\r\n return notificationElem;\r\n };\r\n NotyfView.prototype._createHTMLElement = function (_a) {\r\n var tagName = _a.tagName, className = _a.className, text = _a.text;\r\n var elem = document.createElement(tagName);\r\n if (className) {\r\n elem.className = className;\r\n }\r\n elem.textContent = text || null;\r\n return elem;\r\n };\r\n /**\r\n * Creates an invisible container which will announce the notyfs to\r\n * screen readers\r\n */\r\n NotyfView.prototype._createA11yContainer = function () {\r\n var a11yContainer = this._createHTMLElement({ tagName: 'div', className: 'notyf-announcer' });\r\n a11yContainer.setAttribute('aria-atomic', 'true');\r\n a11yContainer.setAttribute('aria-live', 'polite');\r\n // Set the a11y container to be visible hidden. Can't use display: none as\r\n // screen readers won't read it.\r\n a11yContainer.style.border = '0';\r\n a11yContainer.style.clip = 'rect(0 0 0 0)';\r\n a11yContainer.style.height = '1px';\r\n a11yContainer.style.margin = '-1px';\r\n a11yContainer.style.overflow = 'hidden';\r\n a11yContainer.style.padding = '0';\r\n a11yContainer.style.position = 'absolute';\r\n a11yContainer.style.width = '1px';\r\n a11yContainer.style.outline = '0';\r\n document.body.appendChild(a11yContainer);\r\n this.a11yContainer = a11yContainer;\r\n };\r\n /**\r\n * Announces a message to screenreaders.\r\n */\r\n NotyfView.prototype._announce = function (message) {\r\n var _this = this;\r\n this.a11yContainer.textContent = '';\r\n // This 100ms timeout is necessary for some browser + screen-reader combinations:\r\n // - Both JAWS and NVDA over IE11 will not announce anything without a non-zero timeout.\r\n // - With Chrome and IE11 with NVDA or JAWS, a repeated (identical) message won't be read a\r\n // second time without clearing and then using a non-zero delay.\r\n // (using JAWS 17 at time of this writing).\r\n // https://github.com/angular/material2/blob/master/src/cdk/a11y/live-announcer/live-announcer.ts\r\n setTimeout(function () {\r\n _this.a11yContainer.textContent = message;\r\n }, 100);\r\n };\r\n /**\r\n * Determine which animationend event is supported\r\n */\r\n NotyfView.prototype._getAnimationEndEventName = function () {\r\n var el = document.createElement('_fake');\r\n var transitions = {\r\n MozTransition: 'animationend',\r\n OTransition: 'oAnimationEnd',\r\n WebkitTransition: 'webkitAnimationEnd',\r\n transition: 'animationend',\r\n };\r\n var t;\r\n for (t in transitions) {\r\n if (el.style[t] !== undefined) {\r\n return transitions[t];\r\n }\r\n }\r\n // No supported animation end event. Using \"animationend\" as a fallback\r\n return 'animationend';\r\n };\r\n return NotyfView;\r\n}());\n\n/**\r\n * Main controller class. Defines the main Notyf API.\r\n */\r\nvar Notyf = /** @class */ (function () {\r\n function Notyf(opts) {\r\n var _this = this;\r\n this.dismiss = this._removeNotification;\r\n this.notifications = new NotyfArray();\r\n this.view = new NotyfView();\r\n var types = this.registerTypes(opts);\r\n this.options = __assign(__assign({}, DEFAULT_OPTIONS), opts);\r\n this.options.types = types;\r\n this.notifications.onUpdate(function (elem, type) { return _this.view.update(elem, type); });\r\n this.view.on(NotyfEvent.Dismiss, function (_a) {\r\n var target = _a.target, event = _a.event;\r\n _this._removeNotification(target);\r\n // tslint:disable-next-line: no-string-literal\r\n target['triggerEvent'](NotyfEvent.Dismiss, event);\r\n });\r\n // tslint:disable-next-line: no-string-literal\r\n this.view.on(NotyfEvent.Click, function (_a) {\r\n var target = _a.target, event = _a.event;\r\n return target['triggerEvent'](NotyfEvent.Click, event);\r\n });\r\n }\r\n Notyf.prototype.error = function (payload) {\r\n var options = this.normalizeOptions('error', payload);\r\n return this.open(options);\r\n };\r\n Notyf.prototype.success = function (payload) {\r\n var options = this.normalizeOptions('success', payload);\r\n return this.open(options);\r\n };\r\n Notyf.prototype.open = function (options) {\r\n var defaultOpts = this.options.types.find(function (_a) {\r\n var type = _a.type;\r\n return type === options.type;\r\n }) || {};\r\n var config = __assign(__assign({}, defaultOpts), options);\r\n this.assignProps(['ripple', 'position', 'dismissible'], config);\r\n var notification = new NotyfNotification(config);\r\n this._pushNotification(notification);\r\n return notification;\r\n };\r\n Notyf.prototype.dismissAll = function () {\r\n while (this.notifications.splice(0, 1))\r\n ;\r\n };\r\n /**\r\n * Assigns properties to a config object based on two rules:\r\n * 1. If the config object already sets that prop, leave it as so\r\n * 2. Otherwise, use the default prop from the global options\r\n *\r\n * It's intended to build the final config object to open a notification. e.g. if\r\n * 'dismissible' is not set, then use the value from the global config.\r\n *\r\n * @param props - properties to be assigned to the config object\r\n * @param config - object whose properties need to be set\r\n */\r\n Notyf.prototype.assignProps = function (props, config) {\r\n var _this = this;\r\n props.forEach(function (prop) {\r\n // intentional double equality to check for both null and undefined\r\n config[prop] = config[prop] == null ? _this.options[prop] : config[prop];\r\n });\r\n };\r\n Notyf.prototype._pushNotification = function (notification) {\r\n var _this = this;\r\n this.notifications.push(notification);\r\n var duration = notification.options.duration !== undefined ? notification.options.duration : this.options.duration;\r\n if (duration) {\r\n setTimeout(function () { return _this._removeNotification(notification); }, duration);\r\n }\r\n };\r\n Notyf.prototype._removeNotification = function (notification) {\r\n var index = this.notifications.indexOf(notification);\r\n if (index !== -1) {\r\n this.notifications.splice(index, 1);\r\n }\r\n };\r\n Notyf.prototype.normalizeOptions = function (type, payload) {\r\n var options = { type: type };\r\n if (typeof payload === 'string') {\r\n options.message = payload;\r\n }\r\n else if (typeof payload === 'object') {\r\n options = __assign(__assign({}, options), payload);\r\n }\r\n return options;\r\n };\r\n Notyf.prototype.registerTypes = function (opts) {\r\n var incomingTypes = ((opts && opts.types) || []).slice();\r\n var finalDefaultTypes = DEFAULT_OPTIONS.types.map(function (defaultType) {\r\n // find if there's a default type within the user input's types, if so, it means the user\r\n // wants to change some of the default settings\r\n var userTypeIdx = -1;\r\n incomingTypes.forEach(function (t, idx) {\r\n if (t.type === defaultType.type)\r\n userTypeIdx = idx;\r\n });\r\n var userType = userTypeIdx !== -1 ? incomingTypes.splice(userTypeIdx, 1)[0] : {};\r\n return __assign(__assign({}, defaultType), userType);\r\n });\r\n return finalDefaultTypes.concat(incomingTypes);\r\n };\r\n return Notyf;\r\n}());\n\nexport { DEFAULT_OPTIONS, Notyf, NotyfArray, NotyfArrayEvent, NotyfEvent, NotyfNotification, NotyfView };\n", "import {INotyfOptions, Notyf, NotyfNotification} from \"notyf\";\n\nlet notyfConf: INotyfOptions = {\n\tposition: {x: \"right\", y: \"bottom\"},\n\tduration: 6000,\n\tripple: false,\n\tdismissible: true,\n\ttypes: [\n\t\t{\n\t\t\ttype: \"info\",\n\t\t\tbackground: \"blue\",\n\t\t\ticon: {\n\t\t\t\tclassName: \"fas fa-info-circle\",\n\t\t\t\ttagName: \"i\",\n\t\t\t\tcolor: \"white\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\ttype: \"error\",\n\t\t\tbackground: \"red\",\n\t\t\ticon: {\n\t\t\t\tclassName: \"fas fa-exclamation-triangle\",\n\t\t\t\ttagName: \"i\",\n\t\t\t\tcolor: \"white\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\ttype: \"success\",\n\t\t\tbackground: \"green\",\n\t\t\ticon: {\n\t\t\t\tclassName: \"fas fa-check-circle\",\n\t\t\t\ttagName: \"i\",\n\t\t\t\tcolor: \"white\",\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\ttype: \"progress\",\n\t\t\tbackground: \"blue\",\n\t\t\ticon: false,\n\t\t\tdismissible: false,\n\t\t\tduration: 10000000,\n\t\t},\n\t],\n};\n\nvar notyf: Notyf | null = null;\n\nwindow.addEventListener(\"DOMContentLoaded\", () => {\n\tnotyf = new Notyf(notyfConf);\n});\n\ninterface ToastOptions {\n\ttitle?: string;\n\tdescription?: string;\n\tstatus?: \"success\" | \"error\" | \"info\" | \"progress\";\n}\n\n/* createToast options\n\ttitle: the toast title\n\tdescription: the toast description\n\tstatus: the toast status (default \"info\", can be [\"success\", \"error\", \"info\"])\n*/\nexport function createToast(options: ToastOptions): NotyfNotification | undefined {\n\tif (notyf === null) {\n\t\tconsole.error(\"createToast() called before window load\");\n\t\treturn;\n\t}\n\n\tif (options.status == null) {\n\t\toptions.status = \"info\";\n\t}\n\n\tlet msg = \"\";\n\tif (options.title !== undefined && options.title !== null && options.title !== \"\") {\n\t\tmsg += `

${options.title}

`;\n\t}\n\tif (options.description !== undefined && options.description !== null && options.description !== \"\") {\n\t\tmsg += options.description;\n\t}\n\n\treturn notyf.open({\n\t\ttype: options.status,\n\t\tmessage: msg,\n\t});\n}\n\nexport interface APIResponse {\n\tstatus: \"success\" | \"error\";\n\tdata: any;\n}\n\nexport function apiToast(res: APIResponse, overwrite?: ToastOptions): NotyfNotification | undefined {\n\tif (overwrite === null || overwrite === undefined) {\n\t\toverwrite = {};\n\t}\n\toverwrite[\"status\"] = res.status;\n\toverwrite[\"description\"] = res.data;\n\treturn createToast(overwrite);\n}\n\nexport function dismissToast(toast: NotyfNotification | undefined) {\n\tif (toast === undefined) {\n\t\treturn;\n\t}\n\tnotyf?.dismiss(toast);\n}\n\nwindow.addEventListener(\"DOMContentLoaded\", () => {\n\tdocument.body.addEventListener(\"showToast\", e => {\n\t\tswitch (e.detail.level) {\n\t\t\tcase \"success\":\n\t\t\t\tcreateToast({status: \"success\", description: e.detail.message});\n\t\t\t\tbreak\n\t\t\tcase \"error\":\n\t\t\t\tcreateToast({status: \"error\", description: e.detail.message});\n\t\t\t\tbreak\n\t\t\tdefault:\n\t\t\t\tcreateToast({status: \"info\", description: e.detail.message});\n\t\t\t\tbreak\n\t\t}\n\t})\n})\n", "/*! js-cookie v3.0.5 | MIT */\n/* eslint-disable no-var */\nfunction assign (target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i];\n for (var key in source) {\n target[key] = source[key];\n }\n }\n return target\n}\n/* eslint-enable no-var */\n\n/* eslint-disable no-var */\nvar defaultConverter = {\n read: function (value) {\n if (value[0] === '\"') {\n value = value.slice(1, -1);\n }\n return value.replace(/(%[\\dA-F]{2})+/gi, decodeURIComponent)\n },\n write: function (value) {\n return encodeURIComponent(value).replace(\n /%(2[346BF]|3[AC-F]|40|5[BDE]|60|7[BCD])/g,\n decodeURIComponent\n )\n }\n};\n/* eslint-enable no-var */\n\n/* eslint-disable no-var */\n\nfunction init (converter, defaultAttributes) {\n function set (name, value, attributes) {\n if (typeof document === 'undefined') {\n return\n }\n\n attributes = assign({}, defaultAttributes, attributes);\n\n if (typeof attributes.expires === 'number') {\n attributes.expires = new Date(Date.now() + attributes.expires * 864e5);\n }\n if (attributes.expires) {\n attributes.expires = attributes.expires.toUTCString();\n }\n\n name = encodeURIComponent(name)\n .replace(/%(2[346B]|5E|60|7C)/g, decodeURIComponent)\n .replace(/[()]/g, escape);\n\n var stringifiedAttributes = '';\n for (var attributeName in attributes) {\n if (!attributes[attributeName]) {\n continue\n }\n\n stringifiedAttributes += '; ' + attributeName;\n\n if (attributes[attributeName] === true) {\n continue\n }\n\n // Considers RFC 6265 section 5.2:\n // ...\n // 3. If the remaining unparsed-attributes contains a %x3B (\";\")\n // character:\n // Consume the characters of the unparsed-attributes up to,\n // not including, the first %x3B (\";\") character.\n // ...\n stringifiedAttributes += '=' + attributes[attributeName].split(';')[0];\n }\n\n return (document.cookie =\n name + '=' + converter.write(value, name) + stringifiedAttributes)\n }\n\n function get (name) {\n if (typeof document === 'undefined' || (arguments.length && !name)) {\n return\n }\n\n // To prevent the for loop in the first place assign an empty array\n // in case there are no cookies at all.\n var cookies = document.cookie ? document.cookie.split('; ') : [];\n var jar = {};\n for (var i = 0; i < cookies.length; i++) {\n var parts = cookies[i].split('=');\n var value = parts.slice(1).join('=');\n\n try {\n var found = decodeURIComponent(parts[0]);\n jar[found] = converter.read(value, found);\n\n if (name === found) {\n break\n }\n } catch (e) {}\n }\n\n return name ? jar[name] : jar\n }\n\n return Object.create(\n {\n set,\n get,\n remove: function (name, attributes) {\n set(\n name,\n '',\n assign({}, attributes, {\n expires: -1\n })\n );\n },\n withAttributes: function (attributes) {\n return init(this.converter, assign({}, this.attributes, attributes))\n },\n withConverter: function (converter) {\n return init(assign({}, this.converter, converter), this.attributes)\n }\n },\n {\n attributes: { value: Object.freeze(defaultAttributes) },\n converter: { value: Object.freeze(converter) }\n }\n )\n}\n\nvar api = init(defaultConverter, { path: '/' });\n/* eslint-enable no-var */\n\nexport { api as default };\n", "import decodeComponent from 'decode-uri-component';\nimport {includeKeys} from 'filter-obj';\nimport splitOnFirst from 'split-on-first';\n\nconst isNullOrUndefined = value => value === null || value === undefined;\n\n// eslint-disable-next-line unicorn/prefer-code-point\nconst strictUriEncode = string => encodeURIComponent(string).replaceAll(/[!'()*]/g, x => `%${x.charCodeAt(0).toString(16).toUpperCase()}`);\n\nconst encodeFragmentIdentifier = Symbol('encodeFragmentIdentifier');\n\nfunction encoderForArrayFormat(options) {\n\tswitch (options.arrayFormat) {\n\t\tcase 'index': {\n\t\t\treturn key => (result, value) => {\n\t\t\t\tconst index = result.length;\n\n\t\t\t\tif (\n\t\t\t\t\tvalue === undefined\n\t\t\t\t\t|| (options.skipNull && value === null)\n\t\t\t\t\t|| (options.skipEmptyString && value === '')\n\t\t\t\t) {\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\n\t\t\t\tif (value === null) {\n\t\t\t\t\treturn [\n\t\t\t\t\t\t...result, [encode(key, options), '[', index, ']'].join(''),\n\t\t\t\t\t];\n\t\t\t\t}\n\n\t\t\t\treturn [\n\t\t\t\t\t...result,\n\t\t\t\t\t[encode(key, options), '[', encode(index, options), ']=', encode(value, options)].join(''),\n\t\t\t\t];\n\t\t\t};\n\t\t}\n\n\t\tcase 'bracket': {\n\t\t\treturn key => (result, value) => {\n\t\t\t\tif (\n\t\t\t\t\tvalue === undefined\n\t\t\t\t\t|| (options.skipNull && value === null)\n\t\t\t\t\t|| (options.skipEmptyString && value === '')\n\t\t\t\t) {\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\n\t\t\t\tif (value === null) {\n\t\t\t\t\treturn [\n\t\t\t\t\t\t...result,\n\t\t\t\t\t\t[encode(key, options), '[]'].join(''),\n\t\t\t\t\t];\n\t\t\t\t}\n\n\t\t\t\treturn [\n\t\t\t\t\t...result,\n\t\t\t\t\t[encode(key, options), '[]=', encode(value, options)].join(''),\n\t\t\t\t];\n\t\t\t};\n\t\t}\n\n\t\tcase 'colon-list-separator': {\n\t\t\treturn key => (result, value) => {\n\t\t\t\tif (\n\t\t\t\t\tvalue === undefined\n\t\t\t\t\t|| (options.skipNull && value === null)\n\t\t\t\t\t|| (options.skipEmptyString && value === '')\n\t\t\t\t) {\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\n\t\t\t\tif (value === null) {\n\t\t\t\t\treturn [\n\t\t\t\t\t\t...result,\n\t\t\t\t\t\t[encode(key, options), ':list='].join(''),\n\t\t\t\t\t];\n\t\t\t\t}\n\n\t\t\t\treturn [\n\t\t\t\t\t...result,\n\t\t\t\t\t[encode(key, options), ':list=', encode(value, options)].join(''),\n\t\t\t\t];\n\t\t\t};\n\t\t}\n\n\t\tcase 'comma':\n\t\tcase 'separator':\n\t\tcase 'bracket-separator': {\n\t\t\tconst keyValueSeparator = options.arrayFormat === 'bracket-separator'\n\t\t\t\t? '[]='\n\t\t\t\t: '=';\n\n\t\t\treturn key => (result, value) => {\n\t\t\t\tif (\n\t\t\t\t\tvalue === undefined\n\t\t\t\t\t|| (options.skipNull && value === null)\n\t\t\t\t\t|| (options.skipEmptyString && value === '')\n\t\t\t\t) {\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\n\t\t\t\t// Translate null to an empty string so that it doesn't serialize as 'null'\n\t\t\t\tvalue = value === null ? '' : value;\n\n\t\t\t\tif (result.length === 0) {\n\t\t\t\t\treturn [[encode(key, options), keyValueSeparator, encode(value, options)].join('')];\n\t\t\t\t}\n\n\t\t\t\treturn [[result, encode(value, options)].join(options.arrayFormatSeparator)];\n\t\t\t};\n\t\t}\n\n\t\tdefault: {\n\t\t\treturn key => (result, value) => {\n\t\t\t\tif (\n\t\t\t\t\tvalue === undefined\n\t\t\t\t\t|| (options.skipNull && value === null)\n\t\t\t\t\t|| (options.skipEmptyString && value === '')\n\t\t\t\t) {\n\t\t\t\t\treturn result;\n\t\t\t\t}\n\n\t\t\t\tif (value === null) {\n\t\t\t\t\treturn [\n\t\t\t\t\t\t...result,\n\t\t\t\t\t\tencode(key, options),\n\t\t\t\t\t];\n\t\t\t\t}\n\n\t\t\t\treturn [\n\t\t\t\t\t...result,\n\t\t\t\t\t[encode(key, options), '=', encode(value, options)].join(''),\n\t\t\t\t];\n\t\t\t};\n\t\t}\n\t}\n}\n\nfunction parserForArrayFormat(options) {\n\tlet result;\n\n\tswitch (options.arrayFormat) {\n\t\tcase 'index': {\n\t\t\treturn (key, value, accumulator) => {\n\t\t\t\tresult = /\\[(\\d*)]$/.exec(key);\n\n\t\t\t\tkey = key.replace(/\\[\\d*]$/, '');\n\n\t\t\t\tif (!result) {\n\t\t\t\t\taccumulator[key] = value;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (accumulator[key] === undefined) {\n\t\t\t\t\taccumulator[key] = {};\n\t\t\t\t}\n\n\t\t\t\taccumulator[key][result[1]] = value;\n\t\t\t};\n\t\t}\n\n\t\tcase 'bracket': {\n\t\t\treturn (key, value, accumulator) => {\n\t\t\t\tresult = /(\\[])$/.exec(key);\n\t\t\t\tkey = key.replace(/\\[]$/, '');\n\n\t\t\t\tif (!result) {\n\t\t\t\t\taccumulator[key] = value;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (accumulator[key] === undefined) {\n\t\t\t\t\taccumulator[key] = [value];\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\taccumulator[key] = [...accumulator[key], value];\n\t\t\t};\n\t\t}\n\n\t\tcase 'colon-list-separator': {\n\t\t\treturn (key, value, accumulator) => {\n\t\t\t\tresult = /(:list)$/.exec(key);\n\t\t\t\tkey = key.replace(/:list$/, '');\n\n\t\t\t\tif (!result) {\n\t\t\t\t\taccumulator[key] = value;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (accumulator[key] === undefined) {\n\t\t\t\t\taccumulator[key] = [value];\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\taccumulator[key] = [...accumulator[key], value];\n\t\t\t};\n\t\t}\n\n\t\tcase 'comma':\n\t\tcase 'separator': {\n\t\t\treturn (key, value, accumulator) => {\n\t\t\t\tconst isArray = typeof value === 'string' && value.includes(options.arrayFormatSeparator);\n\t\t\t\tconst isEncodedArray = (typeof value === 'string' && !isArray && decode(value, options).includes(options.arrayFormatSeparator));\n\t\t\t\tvalue = isEncodedArray ? decode(value, options) : value;\n\t\t\t\tconst newValue = isArray || isEncodedArray ? value.split(options.arrayFormatSeparator).map(item => decode(item, options)) : (value === null ? value : decode(value, options));\n\t\t\t\taccumulator[key] = newValue;\n\t\t\t};\n\t\t}\n\n\t\tcase 'bracket-separator': {\n\t\t\treturn (key, value, accumulator) => {\n\t\t\t\tconst isArray = /(\\[])$/.test(key);\n\t\t\t\tkey = key.replace(/\\[]$/, '');\n\n\t\t\t\tif (!isArray) {\n\t\t\t\t\taccumulator[key] = value ? decode(value, options) : value;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst arrayValue = value === null\n\t\t\t\t\t? []\n\t\t\t\t\t: decode(value, options).split(options.arrayFormatSeparator);\n\n\t\t\t\tif (accumulator[key] === undefined) {\n\t\t\t\t\taccumulator[key] = arrayValue;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\taccumulator[key] = [...accumulator[key], ...arrayValue];\n\t\t\t};\n\t\t}\n\n\t\tdefault: {\n\t\t\treturn (key, value, accumulator) => {\n\t\t\t\tif (accumulator[key] === undefined) {\n\t\t\t\t\taccumulator[key] = value;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\taccumulator[key] = [...[accumulator[key]].flat(), value];\n\t\t\t};\n\t\t}\n\t}\n}\n\nfunction validateArrayFormatSeparator(value) {\n\tif (typeof value !== 'string' || value.length !== 1) {\n\t\tthrow new TypeError('arrayFormatSeparator must be single character string');\n\t}\n}\n\nfunction encode(value, options) {\n\tif (options.encode) {\n\t\treturn options.strict ? strictUriEncode(value) : encodeURIComponent(value);\n\t}\n\n\treturn value;\n}\n\nfunction decode(value, options) {\n\tif (options.decode) {\n\t\treturn decodeComponent(value);\n\t}\n\n\treturn value;\n}\n\nfunction keysSorter(input) {\n\tif (Array.isArray(input)) {\n\t\treturn input.sort();\n\t}\n\n\tif (typeof input === 'object') {\n\t\treturn keysSorter(Object.keys(input))\n\t\t\t.sort((a, b) => Number(a) - Number(b))\n\t\t\t.map(key => input[key]);\n\t}\n\n\treturn input;\n}\n\nfunction removeHash(input) {\n\tconst hashStart = input.indexOf('#');\n\tif (hashStart !== -1) {\n\t\tinput = input.slice(0, hashStart);\n\t}\n\n\treturn input;\n}\n\nfunction getHash(url) {\n\tlet hash = '';\n\tconst hashStart = url.indexOf('#');\n\tif (hashStart !== -1) {\n\t\thash = url.slice(hashStart);\n\t}\n\n\treturn hash;\n}\n\nfunction parseValue(value, options, type) {\n\tif (type === 'string' && typeof value === 'string') {\n\t\treturn value;\n\t}\n\n\tif (typeof type === 'function' && typeof value === 'string') {\n\t\treturn type(value);\n\t}\n\n\tif (options.parseBooleans && value !== null && (value.toLowerCase() === 'true' || value.toLowerCase() === 'false')) {\n\t\treturn value.toLowerCase() === 'true';\n\t}\n\n\tif (type === 'number' && !Number.isNaN(Number(value)) && (typeof value === 'string' && value.trim() !== '')) {\n\t\treturn Number(value);\n\t}\n\n\tif (options.parseNumbers && !Number.isNaN(Number(value)) && (typeof value === 'string' && value.trim() !== '')) {\n\t\treturn Number(value);\n\t}\n\n\treturn value;\n}\n\nexport function extract(input) {\n\tinput = removeHash(input);\n\tconst queryStart = input.indexOf('?');\n\tif (queryStart === -1) {\n\t\treturn '';\n\t}\n\n\treturn input.slice(queryStart + 1);\n}\n\nexport function parse(query, options) {\n\toptions = {\n\t\tdecode: true,\n\t\tsort: true,\n\t\tarrayFormat: 'none',\n\t\tarrayFormatSeparator: ',',\n\t\tparseNumbers: false,\n\t\tparseBooleans: false,\n\t\ttypes: Object.create(null),\n\t\t...options,\n\t};\n\n\tvalidateArrayFormatSeparator(options.arrayFormatSeparator);\n\n\tconst formatter = parserForArrayFormat(options);\n\n\t// Create an object with no prototype\n\tconst returnValue = Object.create(null);\n\n\tif (typeof query !== 'string') {\n\t\treturn returnValue;\n\t}\n\n\tquery = query.trim().replace(/^[?#&]/, '');\n\n\tif (!query) {\n\t\treturn returnValue;\n\t}\n\n\tfor (const parameter of query.split('&')) {\n\t\tif (parameter === '') {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst parameter_ = options.decode ? parameter.replaceAll('+', ' ') : parameter;\n\n\t\tlet [key, value] = splitOnFirst(parameter_, '=');\n\n\t\tif (key === undefined) {\n\t\t\tkey = parameter_;\n\t\t}\n\n\t\t// Missing `=` should be `null`:\n\t\t// http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters\n\t\tvalue = value === undefined ? null : (['comma', 'separator', 'bracket-separator'].includes(options.arrayFormat) ? value : decode(value, options));\n\t\tformatter(decode(key, options), value, returnValue);\n\t}\n\n\tfor (const [key, value] of Object.entries(returnValue)) {\n\t\tif (typeof value === 'object' && value !== null && options.types[key] !== 'string') {\n\t\t\tfor (const [key2, value2] of Object.entries(value)) {\n\t\t\t\tconst type = options.types[key] ? options.types[key].replace('[]', '') : undefined;\n\t\t\t\tvalue[key2] = parseValue(value2, options, type);\n\t\t\t}\n\t\t} else if (typeof value === 'object' && value !== null && options.types[key] === 'string') {\n\t\t\treturnValue[key] = Object.values(value).join(options.arrayFormatSeparator);\n\t\t} else {\n\t\t\treturnValue[key] = parseValue(value, options, options.types[key]);\n\t\t}\n\t}\n\n\tif (options.sort === false) {\n\t\treturn returnValue;\n\t}\n\n\t// TODO: Remove the use of `reduce`.\n\t// eslint-disable-next-line unicorn/no-array-reduce\n\treturn (options.sort === true ? Object.keys(returnValue).sort() : Object.keys(returnValue).sort(options.sort)).reduce((result, key) => {\n\t\tconst value = returnValue[key];\n\t\tresult[key] = Boolean(value) && typeof value === 'object' && !Array.isArray(value) ? keysSorter(value) : value;\n\t\treturn result;\n\t}, Object.create(null));\n}\n\nexport function stringify(object, options) {\n\tif (!object) {\n\t\treturn '';\n\t}\n\n\toptions = {\n\t\tencode: true,\n\t\tstrict: true,\n\t\tarrayFormat: 'none',\n\t\tarrayFormatSeparator: ',',\n\t\t...options,\n\t};\n\n\tvalidateArrayFormatSeparator(options.arrayFormatSeparator);\n\n\tconst shouldFilter = key => (\n\t\t(options.skipNull && isNullOrUndefined(object[key]))\n\t\t|| (options.skipEmptyString && object[key] === '')\n\t);\n\n\tconst formatter = encoderForArrayFormat(options);\n\n\tconst objectCopy = {};\n\n\tfor (const [key, value] of Object.entries(object)) {\n\t\tif (!shouldFilter(key)) {\n\t\t\tobjectCopy[key] = value;\n\t\t}\n\t}\n\n\tconst keys = Object.keys(objectCopy);\n\n\tif (options.sort !== false) {\n\t\tkeys.sort(options.sort);\n\t}\n\n\treturn keys.map(key => {\n\t\tconst value = object[key];\n\n\t\tif (value === undefined) {\n\t\t\treturn '';\n\t\t}\n\n\t\tif (value === null) {\n\t\t\treturn encode(key, options);\n\t\t}\n\n\t\tif (Array.isArray(value)) {\n\t\t\tif (value.length === 0 && options.arrayFormat === 'bracket-separator') {\n\t\t\t\treturn encode(key, options) + '[]';\n\t\t\t}\n\n\t\t\treturn value\n\t\t\t\t.reduce(formatter(key), [])\n\t\t\t\t.join('&');\n\t\t}\n\n\t\treturn encode(key, options) + '=' + encode(value, options);\n\t}).filter(x => x.length > 0).join('&');\n}\n\nexport function parseUrl(url, options) {\n\toptions = {\n\t\tdecode: true,\n\t\t...options,\n\t};\n\n\tlet [url_, hash] = splitOnFirst(url, '#');\n\n\tif (url_ === undefined) {\n\t\turl_ = url;\n\t}\n\n\treturn {\n\t\turl: url_?.split('?')?.[0] ?? '',\n\t\tquery: parse(extract(url), options),\n\t\t...(options && options.parseFragmentIdentifier && hash ? {fragmentIdentifier: decode(hash, options)} : {}),\n\t};\n}\n\nexport function stringifyUrl(object, options) {\n\toptions = {\n\t\tencode: true,\n\t\tstrict: true,\n\t\t[encodeFragmentIdentifier]: true,\n\t\t...options,\n\t};\n\n\tconst url = removeHash(object.url).split('?')[0] || '';\n\tconst queryFromUrl = extract(object.url);\n\n\tconst query = {\n\t\t...parse(queryFromUrl, {sort: false}),\n\t\t...object.query,\n\t};\n\n\tlet queryString = stringify(query, options);\n\tqueryString &&= `?${queryString}`;\n\n\tlet hash = getHash(object.url);\n\tif (typeof object.fragmentIdentifier === 'string') {\n\t\tconst urlObjectForFragmentEncode = new URL(url);\n\t\turlObjectForFragmentEncode.hash = object.fragmentIdentifier;\n\t\thash = options[encodeFragmentIdentifier] ? urlObjectForFragmentEncode.hash : `#${object.fragmentIdentifier}`;\n\t}\n\n\treturn `${url}${queryString}${hash}`;\n}\n\nexport function pick(input, filter, options) {\n\toptions = {\n\t\tparseFragmentIdentifier: true,\n\t\t[encodeFragmentIdentifier]: false,\n\t\t...options,\n\t};\n\n\tconst {url, query, fragmentIdentifier} = parseUrl(input, options);\n\n\treturn stringifyUrl({\n\t\turl,\n\t\tquery: includeKeys(query, filter),\n\t\tfragmentIdentifier,\n\t}, options);\n}\n\nexport function exclude(input, filter, options) {\n\tconst exclusionFilter = Array.isArray(filter) ? key => !filter.includes(key) : (key, value) => !filter(key, value);\n\n\treturn pick(input, exclusionFilter, options);\n}\n", "const token = '%[a-f0-9]{2}';\nconst singleMatcher = new RegExp('(' + token + ')|([^%]+?)', 'gi');\nconst multiMatcher = new RegExp('(' + token + ')+', 'gi');\n\nfunction decodeComponents(components, split) {\n\ttry {\n\t\t// Try to decode the entire string first\n\t\treturn [decodeURIComponent(components.join(''))];\n\t} catch {\n\t\t// Do nothing\n\t}\n\n\tif (components.length === 1) {\n\t\treturn components;\n\t}\n\n\tsplit = split || 1;\n\n\t// Split the array in 2 parts\n\tconst left = components.slice(0, split);\n\tconst right = components.slice(split);\n\n\treturn Array.prototype.concat.call([], decodeComponents(left), decodeComponents(right));\n}\n\nfunction decode(input) {\n\ttry {\n\t\treturn decodeURIComponent(input);\n\t} catch {\n\t\tlet tokens = input.match(singleMatcher) || [];\n\n\t\tfor (let i = 1; i < tokens.length; i++) {\n\t\t\tinput = decodeComponents(tokens, i).join('');\n\n\t\t\ttokens = input.match(singleMatcher) || [];\n\t\t}\n\n\t\treturn input;\n\t}\n}\n\nfunction customDecodeURIComponent(input) {\n\t// Keep track of all the replacements and prefill the map with the `BOM`\n\tconst replaceMap = {\n\t\t'%FE%FF': '\\uFFFD\\uFFFD',\n\t\t'%FF%FE': '\\uFFFD\\uFFFD',\n\t};\n\n\tlet match = multiMatcher.exec(input);\n\twhile (match) {\n\t\ttry {\n\t\t\t// Decode as big chunks as possible\n\t\t\treplaceMap[match[0]] = decodeURIComponent(match[0]);\n\t\t} catch {\n\t\t\tconst result = decode(match[0]);\n\n\t\t\tif (result !== match[0]) {\n\t\t\t\treplaceMap[match[0]] = result;\n\t\t\t}\n\t\t}\n\n\t\tmatch = multiMatcher.exec(input);\n\t}\n\n\t// Add `%C2` at the end of the map to make sure it does not replace the combinator before everything else\n\treplaceMap['%C2'] = '\\uFFFD';\n\n\tconst entries = Object.keys(replaceMap);\n\n\tfor (const key of entries) {\n\t\t// Replace all decoded components\n\t\tinput = input.replace(new RegExp(key, 'g'), replaceMap[key]);\n\t}\n\n\treturn input;\n}\n\nexport default function decodeUriComponent(encodedURI) {\n\tif (typeof encodedURI !== 'string') {\n\t\tthrow new TypeError('Expected `encodedURI` to be of type `string`, got `' + typeof encodedURI + '`');\n\t}\n\n\ttry {\n\t\t// Try the built in decoder first\n\t\treturn decodeURIComponent(encodedURI);\n\t} catch {\n\t\t// Fallback to a more advanced decoder\n\t\treturn customDecodeURIComponent(encodedURI);\n\t}\n}\n", "export function includeKeys(object, predicate) {\n\tconst result = {};\n\n\tif (Array.isArray(predicate)) {\n\t\tfor (const key of predicate) {\n\t\t\tconst descriptor = Object.getOwnPropertyDescriptor(object, key);\n\t\t\tif (descriptor?.enumerable) {\n\t\t\t\tObject.defineProperty(result, key, descriptor);\n\t\t\t}\n\t\t}\n\t} else {\n\t\t// `Reflect.ownKeys()` is required to retrieve symbol properties\n\t\tfor (const key of Reflect.ownKeys(object)) {\n\t\t\tconst descriptor = Object.getOwnPropertyDescriptor(object, key);\n\t\t\tif (descriptor.enumerable) {\n\t\t\t\tconst value = object[key];\n\t\t\t\tif (predicate(key, value, object)) {\n\t\t\t\t\tObject.defineProperty(result, key, descriptor);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn result;\n}\n\nexport function excludeKeys(object, predicate) {\n\tif (Array.isArray(predicate)) {\n\t\tconst set = new Set(predicate);\n\t\treturn includeKeys(object, key => !set.has(key));\n\t}\n\n\treturn includeKeys(object, (key, value, object) => !predicate(key, value, object));\n}\n", "export default function splitOnFirst(string, separator) {\n\tif (!(typeof string === 'string' && typeof separator === 'string')) {\n\t\tthrow new TypeError('Expected the arguments to be of type `string`');\n\t}\n\n\tif (string === '' || separator === '') {\n\t\treturn [];\n\t}\n\n\tconst separatorIndex = string.indexOf(separator);\n\n\tif (separatorIndex === -1) {\n\t\treturn [];\n\t}\n\n\treturn [\n\t\tstring.slice(0, separatorIndex),\n\t\tstring.slice(separatorIndex + separator.length)\n\t];\n}\n", "import * as queryString from './base.js';\n\nexport default queryString;\n", "import cookie from \"js-cookie\";\nimport qs from \"query-string\";\n\nexport type ResultSubmission = {\n\tsub: Submission;\n\tauthor: UserBrief;\n\tproblem?: Problem;\n};\n\nexport type SubmissionQuery = {\n\tuser_id?: number;\n\tproblem_id?: number;\n\tproblem_list_id?: number;\n\tcontest_id?: number;\n\tscore?: number;\n\tstatus?: string;\n\tlang?: string;\n\n\tpage: number;\n\n\tcompile_error?: boolean;\n\tordering?: string;\n\tascending?: boolean;\n\n\tlimit?: number;\n};\n\ntype RequestParams = {\n\turl: string;\n\tmethod: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\";\n\tqueryParams?: any;\n\tbody?: BodyInit;\n\theaders?: HeadersInit;\n\tsignal?: AbortSignal;\n};\n\nexport type Submissions = {\n\tsubmissions: Submission[];\n\tcount: number;\n\ttruncated_count: boolean;\n\tusers: Record;\n\tproblems: Record;\n};\n\nexport type Response = { status: \"error\"; data: string; statusCode: number } | { status: \"success\"; data: T; statusCode: number };\n\nexport class KNClient {\n\tsession: string;\n\n\tconstructor(session: string, base: string) {\n\t\tthis.session = session;\n\t}\n\n\tsetSession(newSession: string) {\n\t\tthis.session = newSession;\n\t}\n\n\tasync request(params: RequestParams): Promise> {\n\t\tif (params.url.startsWith(\"/\")) {\n\t\t\tparams.url = params.url.substring(1);\n\t\t}\n\t\ttry {\n\t\t\tlet resp = await fetch(`/api/${params.url}?${qs.stringify(params.queryParams)}`, {\n\t\t\t\tmethod: params.method,\n\t\t\t\theaders: {\n\t\t\t\t\tAccept: \"application/json\",\n\t\t\t\t\tAuthorization: this.session,\n\t\t\t\t\t...params.headers,\n\t\t\t\t},\n\t\t\t\tbody: params.body || null,\n\t\t\t\tsignal: params.signal,\n\t\t\t});\n\t\t\tlet data = (await resp.json()) as Response;\n\t\t\tdata.statusCode = resp.status;\n\t\t\treturn data;\n\t\t} catch (e: any) {\n\t\t\treturn { status: \"error\", data: e.toString(), statusCode: 999 };\n\t\t}\n\t}\n\n\tasync getSubmissions(q: SubmissionQuery) {\n\t\tlet res = await this.request({\n\t\t\turl: \"/submissions/get\",\n\t\t\tmethod: \"GET\",\n\t\t\tqueryParams: {\n\t\t\t\tordering: typeof q.ordering !== \"undefined\" ? q.ordering : \"id\",\n\t\t\t\tascending: (typeof q.ordering !== \"undefined\" && q.ascending) || false,\n\t\t\t\tuser_id: typeof q.user_id !== \"undefined\" && q.user_id > 0 ? q.user_id : undefined,\n\t\t\t\tproblem_id: typeof q.problem_id !== \"undefined\" && q.problem_id > 0 ? q.problem_id : undefined,\n\t\t\t\tproblem_list_id: typeof q.problem_list_id !== \"undefined\" && q.problem_list_id > 0 ? q.problem_list_id : undefined,\n\t\t\t\tcontest_id: typeof q.contest_id !== \"undefined\" && q.contest_id > 0 ? q.contest_id : undefined,\n\t\t\t\tstatus: q.status !== \"\" ? q.status : undefined,\n\t\t\t\tscore: typeof q.score !== \"undefined\" && q.score >= 0 ? q.score : undefined,\n\t\t\t\tlang: typeof q.lang !== \"undefined\" && q.lang !== \"\" ? q.lang : undefined,\n\t\t\t\tcompile_error: q.compile_error,\n\t\t\t\toffset: (q.page - 1) * 50,\n\t\t\t\tlimit: typeof q.limit !== \"undefined\" && q.limit > 0 ? q.limit : 50,\n\t\t\t},\n\t\t});\n\t\tif (res.status === \"error\") {\n\t\t\tthrow new Error(res.data);\n\t\t}\n\t\treturn res.data;\n\t}\n\n\tasync getSubmission(id: number) {\n\t\tlet res = await this.request({\n\t\t\turl: \"/submissions/getByID\",\n\t\t\tmethod: \"GET\",\n\t\t\tqueryParams: { id: id },\n\t\t});\n\t\tif (res.status === \"error\") {\n\t\t\tthrow new Error(res.data);\n\t\t}\n\t\treturn res.data;\n\t}\n\n\tasync getUser(id: number) {\n\t\tlet res = await this.request({\n\t\t\turl: `/user/byID/${id}`,\n\t\t\tmethod: \"GET\",\n\t\t\tqueryParams: {},\n\t\t});\n\t\tif (res.status === \"error\") {\n\t\t\tthrow new Error(res.data);\n\t\t}\n\t\treturn res.data;\n\t}\n}\n\nexport const defaultClient = new KNClient(cookie.get(\"kn-sessionid\") || \"guest\", \"/api\");\n\nexport async function getCall(call: string, params: any, signal?: AbortSignal): Promise> {\n\treturn defaultClient.request({\n\t\turl: call,\n\t\tmethod: \"GET\",\n\t\tqueryParams: params,\n\t\tsignal: signal,\n\t});\n}\n\nexport async function postCall(call: string, params: any): Promise> {\n\treturn defaultClient.request({\n\t\turl: call,\n\t\tmethod: \"POST\",\n\t\theaders: {\n\t\t\t\"Content-Type\": \"application/x-www-form-urlencoded\",\n\t\t},\n\t\tbody: qs.stringify(params),\n\t});\n}\n\nexport async function bodyCall(call: string, body: any): Promise> {\n\treturn defaultClient.request({\n\t\turl: call,\n\t\tmethod: \"POST\",\n\t\theaders: {\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t},\n\t\tbody: JSON.stringify(body),\n\t});\n}\n\nexport async function multipartCall(call: string, formdata: FormData): Promise> {\n\treturn defaultClient.request({\n\t\turl: call,\n\t\tmethod: \"POST\",\n\t\tbody: formdata,\n\t});\n}\n", "// Functions for contest\n\nimport { getCall, postCall } from \"./client\";\nimport { apiToast } from \"../toast\";\n\nexport async function registerForContest(contestID: number) {\n\tconst res = await postCall(`/contest/${contestID}/register`, {});\n\tif (res.status === \"error\") {\n\t\tapiToast(res);\n\t\treturn;\n\t}\n\twindow.location.reload();\n}\n\nexport async function startContestRegistration(contestID: number) {\n\tconst res = await postCall(`/contest/${contestID}/startRegistration`, {});\n\tif (res.status === \"error\") {\n\t\tapiToast(res);\n\t\treturn;\n\t}\n\tif (window.location.pathname.startsWith(`/contests/${contestID}`)) {\n\t\twindow.location.reload();\n\t} else {\n\t\twindow.location.assign(`/contests/${contestID}`);\n\t}\n}\n\nexport async function answerQuestion(q: Question, text: string) {\n\tlet res = await postCall(`/contest/${q.contest_id}/answerQuestion`, { questionID: q.id, text });\n\tapiToast(res);\n\tif (res.status === \"success\") {\n\t\treloadQuestions();\n\t\treturn;\n\t}\n}\n\nexport async function updateAnnouncement(ann: Announcement, text: string) {\n\tlet res = await postCall(`/contest/${ann.contest_id}/updateAnnouncement`, { id: ann.id, text });\n\tapiToast(res);\n\tif (res.status === \"success\") {\n\t\treloadAnnouncements();\n\t\treturn;\n\t}\n}\n\nexport async function deleteAnnouncement(ann: Announcement) {\n\tlet res = await postCall(`/contest/${ann.contest_id}/deleteAnnouncement`, { id: ann.id });\n\tapiToast(res);\n\tif (res.status === \"success\") {\n\t\treloadAnnouncements();\n\t\treturn;\n\t}\n}\n\nexport async function getAllQuestions(contestID: number): Promise {\n\tlet res = await getCall(`/contest/${contestID}/allQuestions`, {});\n\tif (res.status === \"error\") {\n\t\tif (res.statusCode == 401) {\n\t\t\tapiToast({\n\t\t\t\tstatus: \"error\",\n\t\t\t\tdata: \"Error reloading questions (possibly logged out), please report this to the developers. Automatic verification will be disabled for this tab.\",\n\t\t\t});\n\t\t\tstopReloadingQnA();\n\t\t\treturn [];\n\t\t}\n\t\tthrow new Error(res.data);\n\t}\n\treturn res.data;\n}\n\nexport async function getUserQuestions(contestID: number): Promise {\n\tif (window.platform_info.user_id <= 0) {\n\t\t// Skip if unauthed\n\t\treturn [];\n\t}\n\tlet res = await getCall(`/contest/${contestID}/questions`, {});\n\tif (res.status === \"error\") {\n\t\tif (res.statusCode == 401) {\n\t\t\tapiToast({\n\t\t\t\tstatus: \"error\",\n\t\t\t\tdata: \"Error reloading questions (possibly logged out), please report this to the developers. Automatic verification will be disabled for this tab.\",\n\t\t\t});\n\t\t\tstopReloadingQnA();\n\t\t\treturn [];\n\t\t}\n\t\tthrow new Error(res.data);\n\t}\n\treturn res.data;\n}\n\nexport async function getAnnouncements(contestID: number): Promise {\n\tlet res = await getCall(`/contest/${contestID}/announcements`, {});\n\tif (res.status === \"error\") {\n\t\tif (res.statusCode == 401) {\n\t\t\tapiToast({\n\t\t\t\tstatus: \"error\",\n\t\t\t\tdata: \"Error reloading announcements (possibly logged out), please report this to the developers. Automatic verification will be disabled for this tab.\",\n\t\t\t});\n\t\t\tstopReloadingQnA();\n\t\t\treturn [];\n\t\t}\n\t\tthrow new Error(res.data);\n\t}\n\treturn res.data;\n}\n\nexport function reloadQuestions() {\n\tdocument.dispatchEvent(new CustomEvent(\"kn-contest-question-reload\"));\n}\n\nexport function reloadAnnouncements() {\n\tdocument.dispatchEvent(new CustomEvent(\"kn-contest-announcement-reload\"));\n}\n\nvar x: number | undefined;\n\nexport function startReloadingQnA(interval_ms: number) {\n\tx = setInterval(() => {\n\t\treloadQuestions();\n\t\treloadAnnouncements();\n\t}, interval_ms);\n}\n\nexport function stopReloadingQnA() {\n\tconsole.warn(\"Disabling question/answer reloading\");\n\tclearInterval(x);\n}\n", "import dayjs from \"dayjs\";\n// import \"dayjs/locale/ro\";\nimport relativeTime from \"dayjs/plugin/relativeTime\";\nimport customParseFormat from \"dayjs/plugin/customParseFormat\";\n\ndayjs.extend(relativeTime);\ndayjs.extend(customParseFormat);\n\n/*\ndayjs.locale(\"ro\");\n\ndocument.addEventListener(\"DOMContentLoaded\", () => {\n\tdayjs.locale(window.platform_info.language);\n});\n*/\n\nexport { dayjs };\n\nexport { fromBase64 } from \"js-base64\";\n\nexport const JSONTimestamp = \"YYYY-MM-DDTHH:mm:ss.SSSSSSZ\";\n\n// if max_step is 0, it will format until the MB region\n// else if max_step is 1, it will only format until the KB region\n// else if max_step >= 2, it will append a \" B\" to the end of the number\nexport function sizeFormatter(size: number, max_step?: number, floor?: boolean) {\n\tvar units: number = size,\n\t\tsuffix: string = \"B\";\n\tif (max_step === undefined) {\n\t\tmax_step = 0;\n\t}\n\tif (size > 1024 * 1024 && max_step == 0) {\n\t\tunits = Math.round((size / 1024 / 1024) * 1e2) / 1e2;\n\t\tsuffix = \"MB\";\n\t} else if (size > 1024 && max_step <= 1) {\n\t\tunits = Math.round((size / 1024) * 1e2) / 1e2;\n\t\tsuffix = \"KB\";\n\t}\n\tif (floor) {\n\t\tunits = Math.floor(units);\n\t}\n\treturn units + \" \" + suffix;\n}\n\nexport function downloadBlob(blob: Blob, filename: string) {\n\tlet a = document.createElement(\"a\");\n\ta.href = URL.createObjectURL(blob);\n\ta.download = filename;\n\ta.click();\n}\n\nexport function parseTime(str?: string | number, extended?: boolean) {\n\tif (!str) {\n\t\treturn \"\";\n\t}\n\treturn dayjs(str).format(\"DD/MM/YYYY HH:mm\" + (extended ? \":ss\" : \"\"));\n}\n\nexport function getGradient(score: number, maxscore: number) {\n\tlet col = \"#e3dd71\",\n\t\trap = 0.0;\n\tif (maxscore != 0 && score != 0) {\n\t\trap = score / maxscore;\n\t}\n\tif (rap == 1.0) {\n\t\tcol = \"#7fff00\";\n\t}\n\tif (rap < 1.0) {\n\t\tcol = \"#67cf39\";\n\t}\n\tif (rap <= 0.8) {\n\t\tcol = \"#9fdd2e\";\n\t}\n\tif (rap <= 0.6) {\n\t\tcol = \"#d2eb19\";\n\t}\n\tif (rap <= 0.4) {\n\t\tcol = \"#f1d011\";\n\t}\n\tif (rap <= 0.2) {\n\t\tcol = \"#f6881e\";\n\t}\n\tif (rap == 0) {\n\t\tcol = \"#f11722\";\n\t}\n\treturn col;\n}\n\nexport function stringIntToNumber(ints: string[]): number[] {\n\tlet result: number[] = [];\n\tfor (let val of ints.map((val) => parseInt(val))) {\n\t\tif (!isNaN(val)) {\n\t\t\tresult.push(val);\n\t\t}\n\t}\n\treturn result;\n}\n\nexport function navigateBack() {\n\tlet locURL = new URL(document.location.toString());\n\tlet val = locURL.searchParams.get(\"back\");\n\tif (val == null) {\n\t\twindow.location.assign(\"/\");\n\t\treturn;\n\t}\n\tlocURL.pathname = val;\n\tlocURL.search = \"\";\n\twindow.location.assign(locURL);\n}\n\nexport function initialLoad(el: ParentNode) {\n\tel.querySelectorAll(\".server_timestamp\").forEach((val) => {\n\t\tlet timestamp = parseInt(val.innerHTML);\n\t\tif (isNaN(timestamp)) {\n\t\t\tconsole.warn(\"NaN timestamp\");\n\t\t\treturn;\n\t\t}\n\t\tval.innerHTML = parseTime(timestamp, val.classList.contains(\"extended\"));\n\t\tval.classList.remove(\"server_timestamp\");\n\t});\n\tel.querySelectorAll(\".score-cell\").forEach((val) => {\n\t\tconst x = val as HTMLTableCellElement;\n\t\tvar score = parseFloat(x.dataset.score || \"0\");\n\t\tif (isNaN(score)) {\n\t\t\tscore = -1;\n\t\t}\n\t\tif (score > -1) {\n\t\t\t// console.log(x.innerText, score);\n\t\t\tx.style.backgroundColor = getGradient(score, 100);\n\t\t}\n\t\tval.classList.remove(\"score-cell\");\n\t});\n}\n\ndocument.addEventListener(\"DOMContentLoaded\", () => {\n\tinitialLoad(document);\n});\n", "/**\n * base64.ts\n *\n * Licensed under the BSD 3-Clause License.\n * http://opensource.org/licenses/BSD-3-Clause\n *\n * References:\n * http://en.wikipedia.org/wiki/Base64\n *\n * @author Dan Kogai (https://github.com/dankogai)\n */\nconst version = '3.7.7';\n/**\n * @deprecated use lowercase `version`.\n */\nconst VERSION = version;\nconst _hasBuffer = typeof Buffer === 'function';\nconst _TD = typeof TextDecoder === 'function' ? new TextDecoder() : undefined;\nconst _TE = typeof TextEncoder === 'function' ? new TextEncoder() : undefined;\nconst b64ch = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';\nconst b64chs = Array.prototype.slice.call(b64ch);\nconst b64tab = ((a) => {\n let tab = {};\n a.forEach((c, i) => tab[c] = i);\n return tab;\n})(b64chs);\nconst b64re = /^(?:[A-Za-z\\d+\\/]{4})*?(?:[A-Za-z\\d+\\/]{2}(?:==)?|[A-Za-z\\d+\\/]{3}=?)?$/;\nconst _fromCC = String.fromCharCode.bind(String);\nconst _U8Afrom = typeof Uint8Array.from === 'function'\n ? Uint8Array.from.bind(Uint8Array)\n : (it) => new Uint8Array(Array.prototype.slice.call(it, 0));\nconst _mkUriSafe = (src) => src\n .replace(/=/g, '').replace(/[+\\/]/g, (m0) => m0 == '+' ? '-' : '_');\nconst _tidyB64 = (s) => s.replace(/[^A-Za-z0-9\\+\\/]/g, '');\n/**\n * polyfill version of `btoa`\n */\nconst btoaPolyfill = (bin) => {\n // console.log('polyfilled');\n let u32, c0, c1, c2, asc = '';\n const pad = bin.length % 3;\n for (let i = 0; i < bin.length;) {\n if ((c0 = bin.charCodeAt(i++)) > 255 ||\n (c1 = bin.charCodeAt(i++)) > 255 ||\n (c2 = bin.charCodeAt(i++)) > 255)\n throw new TypeError('invalid character found');\n u32 = (c0 << 16) | (c1 << 8) | c2;\n asc += b64chs[u32 >> 18 & 63]\n + b64chs[u32 >> 12 & 63]\n + b64chs[u32 >> 6 & 63]\n + b64chs[u32 & 63];\n }\n return pad ? asc.slice(0, pad - 3) + \"===\".substring(pad) : asc;\n};\n/**\n * does what `window.btoa` of web browsers do.\n * @param {String} bin binary string\n * @returns {string} Base64-encoded string\n */\nconst _btoa = typeof btoa === 'function' ? (bin) => btoa(bin)\n : _hasBuffer ? (bin) => Buffer.from(bin, 'binary').toString('base64')\n : btoaPolyfill;\nconst _fromUint8Array = _hasBuffer\n ? (u8a) => Buffer.from(u8a).toString('base64')\n : (u8a) => {\n // cf. https://stackoverflow.com/questions/12710001/how-to-convert-uint8-array-to-base64-encoded-string/12713326#12713326\n const maxargs = 0x1000;\n let strs = [];\n for (let i = 0, l = u8a.length; i < l; i += maxargs) {\n strs.push(_fromCC.apply(null, u8a.subarray(i, i + maxargs)));\n }\n return _btoa(strs.join(''));\n };\n/**\n * converts a Uint8Array to a Base64 string.\n * @param {boolean} [urlsafe] URL-and-filename-safe a la RFC4648 \u00A75\n * @returns {string} Base64 string\n */\nconst fromUint8Array = (u8a, urlsafe = false) => urlsafe ? _mkUriSafe(_fromUint8Array(u8a)) : _fromUint8Array(u8a);\n// This trick is found broken https://github.com/dankogai/js-base64/issues/130\n// const utob = (src: string) => unescape(encodeURIComponent(src));\n// reverting good old fationed regexp\nconst cb_utob = (c) => {\n if (c.length < 2) {\n var cc = c.charCodeAt(0);\n return cc < 0x80 ? c\n : cc < 0x800 ? (_fromCC(0xc0 | (cc >>> 6))\n + _fromCC(0x80 | (cc & 0x3f)))\n : (_fromCC(0xe0 | ((cc >>> 12) & 0x0f))\n + _fromCC(0x80 | ((cc >>> 6) & 0x3f))\n + _fromCC(0x80 | (cc & 0x3f)));\n }\n else {\n var cc = 0x10000\n + (c.charCodeAt(0) - 0xD800) * 0x400\n + (c.charCodeAt(1) - 0xDC00);\n return (_fromCC(0xf0 | ((cc >>> 18) & 0x07))\n + _fromCC(0x80 | ((cc >>> 12) & 0x3f))\n + _fromCC(0x80 | ((cc >>> 6) & 0x3f))\n + _fromCC(0x80 | (cc & 0x3f)));\n }\n};\nconst re_utob = /[\\uD800-\\uDBFF][\\uDC00-\\uDFFFF]|[^\\x00-\\x7F]/g;\n/**\n * @deprecated should have been internal use only.\n * @param {string} src UTF-8 string\n * @returns {string} UTF-16 string\n */\nconst utob = (u) => u.replace(re_utob, cb_utob);\n//\nconst _encode = _hasBuffer\n ? (s) => Buffer.from(s, 'utf8').toString('base64')\n : _TE\n ? (s) => _fromUint8Array(_TE.encode(s))\n : (s) => _btoa(utob(s));\n/**\n * converts a UTF-8-encoded string to a Base64 string.\n * @param {boolean} [urlsafe] if `true` make the result URL-safe\n * @returns {string} Base64 string\n */\nconst encode = (src, urlsafe = false) => urlsafe\n ? _mkUriSafe(_encode(src))\n : _encode(src);\n/**\n * converts a UTF-8-encoded string to URL-safe Base64 RFC4648 \u00A75.\n * @returns {string} Base64 string\n */\nconst encodeURI = (src) => encode(src, true);\n// This trick is found broken https://github.com/dankogai/js-base64/issues/130\n// const btou = (src: string) => decodeURIComponent(escape(src));\n// reverting good old fationed regexp\nconst re_btou = /[\\xC0-\\xDF][\\x80-\\xBF]|[\\xE0-\\xEF][\\x80-\\xBF]{2}|[\\xF0-\\xF7][\\x80-\\xBF]{3}/g;\nconst cb_btou = (cccc) => {\n switch (cccc.length) {\n case 4:\n var cp = ((0x07 & cccc.charCodeAt(0)) << 18)\n | ((0x3f & cccc.charCodeAt(1)) << 12)\n | ((0x3f & cccc.charCodeAt(2)) << 6)\n | (0x3f & cccc.charCodeAt(3)), offset = cp - 0x10000;\n return (_fromCC((offset >>> 10) + 0xD800)\n + _fromCC((offset & 0x3FF) + 0xDC00));\n case 3:\n return _fromCC(((0x0f & cccc.charCodeAt(0)) << 12)\n | ((0x3f & cccc.charCodeAt(1)) << 6)\n | (0x3f & cccc.charCodeAt(2)));\n default:\n return _fromCC(((0x1f & cccc.charCodeAt(0)) << 6)\n | (0x3f & cccc.charCodeAt(1)));\n }\n};\n/**\n * @deprecated should have been internal use only.\n * @param {string} src UTF-16 string\n * @returns {string} UTF-8 string\n */\nconst btou = (b) => b.replace(re_btou, cb_btou);\n/**\n * polyfill version of `atob`\n */\nconst atobPolyfill = (asc) => {\n // console.log('polyfilled');\n asc = asc.replace(/\\s+/g, '');\n if (!b64re.test(asc))\n throw new TypeError('malformed base64.');\n asc += '=='.slice(2 - (asc.length & 3));\n let u24, bin = '', r1, r2;\n for (let i = 0; i < asc.length;) {\n u24 = b64tab[asc.charAt(i++)] << 18\n | b64tab[asc.charAt(i++)] << 12\n | (r1 = b64tab[asc.charAt(i++)]) << 6\n | (r2 = b64tab[asc.charAt(i++)]);\n bin += r1 === 64 ? _fromCC(u24 >> 16 & 255)\n : r2 === 64 ? _fromCC(u24 >> 16 & 255, u24 >> 8 & 255)\n : _fromCC(u24 >> 16 & 255, u24 >> 8 & 255, u24 & 255);\n }\n return bin;\n};\n/**\n * does what `window.atob` of web browsers do.\n * @param {String} asc Base64-encoded string\n * @returns {string} binary string\n */\nconst _atob = typeof atob === 'function' ? (asc) => atob(_tidyB64(asc))\n : _hasBuffer ? (asc) => Buffer.from(asc, 'base64').toString('binary')\n : atobPolyfill;\n//\nconst _toUint8Array = _hasBuffer\n ? (a) => _U8Afrom(Buffer.from(a, 'base64'))\n : (a) => _U8Afrom(_atob(a).split('').map(c => c.charCodeAt(0)));\n/**\n * converts a Base64 string to a Uint8Array.\n */\nconst toUint8Array = (a) => _toUint8Array(_unURI(a));\n//\nconst _decode = _hasBuffer\n ? (a) => Buffer.from(a, 'base64').toString('utf8')\n : _TD\n ? (a) => _TD.decode(_toUint8Array(a))\n : (a) => btou(_atob(a));\nconst _unURI = (a) => _tidyB64(a.replace(/[-_]/g, (m0) => m0 == '-' ? '+' : '/'));\n/**\n * converts a Base64 string to a UTF-8 string.\n * @param {String} src Base64 string. Both normal and URL-safe are supported\n * @returns {string} UTF-8 string\n */\nconst decode = (src) => _decode(_unURI(src));\n/**\n * check if a value is a valid Base64 string\n * @param {String} src a value to check\n */\nconst isValid = (src) => {\n if (typeof src !== 'string')\n return false;\n const s = src.replace(/\\s+/g, '').replace(/={0,2}$/, '');\n return !/[^\\s0-9a-zA-Z\\+/]/.test(s) || !/[^\\s0-9a-zA-Z\\-_]/.test(s);\n};\n//\nconst _noEnum = (v) => {\n return {\n value: v, enumerable: false, writable: true, configurable: true\n };\n};\n/**\n * extend String.prototype with relevant methods\n */\nconst extendString = function () {\n const _add = (name, body) => Object.defineProperty(String.prototype, name, _noEnum(body));\n _add('fromBase64', function () { return decode(this); });\n _add('toBase64', function (urlsafe) { return encode(this, urlsafe); });\n _add('toBase64URI', function () { return encode(this, true); });\n _add('toBase64URL', function () { return encode(this, true); });\n _add('toUint8Array', function () { return toUint8Array(this); });\n};\n/**\n * extend Uint8Array.prototype with relevant methods\n */\nconst extendUint8Array = function () {\n const _add = (name, body) => Object.defineProperty(Uint8Array.prototype, name, _noEnum(body));\n _add('toBase64', function (urlsafe) { return fromUint8Array(this, urlsafe); });\n _add('toBase64URI', function () { return fromUint8Array(this, true); });\n _add('toBase64URL', function () { return fromUint8Array(this, true); });\n};\n/**\n * extend Builtin prototypes with relevant methods\n */\nconst extendBuiltins = () => {\n extendString();\n extendUint8Array();\n};\nconst gBase64 = {\n version: version,\n VERSION: VERSION,\n atob: _atob,\n atobPolyfill: atobPolyfill,\n btoa: _btoa,\n btoaPolyfill: btoaPolyfill,\n fromBase64: decode,\n toBase64: encode,\n encode: encode,\n encodeURI: encodeURI,\n encodeURL: encodeURI,\n utob: utob,\n btou: btou,\n decode: decode,\n isValid: isValid,\n fromUint8Array: fromUint8Array,\n toUint8Array: toUint8Array,\n extendString: extendString,\n extendUint8Array: extendUint8Array,\n extendBuiltins: extendBuiltins\n};\n// makecjs:CUT //\nexport { version };\nexport { VERSION };\nexport { _atob as atob };\nexport { atobPolyfill };\nexport { _btoa as btoa };\nexport { btoaPolyfill };\nexport { decode as fromBase64 };\nexport { encode as toBase64 };\nexport { utob };\nexport { encode };\nexport { encodeURI };\nexport { encodeURI as encodeURL };\nexport { btou };\nexport { decode };\nexport { isValid };\nexport { fromUint8Array };\nexport { toUint8Array };\nexport { extendString };\nexport { extendUint8Array };\nexport { extendBuiltins };\n// and finally,\nexport { gBase64 as Base64 };\n", "import { vsprintf } from \"sprintf-js\";\nimport languageStrings from \"./_translations.json\";\n\ntype translation = {\n\tro: string;\n\ten: string;\n};\n\nfunction getVal(key: string, maybe: boolean = false): translation | null {\n\tlet current: any = languageStrings;\n\tlet vals = key.split(\".\");\n\tif (current[vals[0]] === undefined) {\n\t\tif (!maybe) {\n\t\t\t// If key must be here, return a warning saying that it isn't..\n\t\t\tconsole.warn(`key \"${key}\" does not exist`);\n\t\t}\n\t\treturn null;\n\t}\n\tfor (const sub of vals) {\n\t\tif(typeof current[sub] === 'undefined') {\n\t\t\treturn null\n\t\t}\n\t\tif (typeof current[sub][\"ro\"] !== 'undefined') {\n\t\t\treturn current[sub];\n\t\t}\n\t\tcurrent = current[sub];\n\t}\n\treturn null;\n}\n\nexport default function getText(key: string, ...args: any): string {\n\tconst lang = window.platform_info.language;\n\tconst translation = getVal(key);\n\tif (translation === null) {\n\t\tconsole.error(\"Unknown key\", JSON.stringify(key));\n\t\treturn \"ERR\";\n\t}\n\tif (lang in translation) {\n\t\treturn vsprintf(translation[lang], args);\n\t}\n\tconsole.error(\"Language\", lang, \"not found in key\", key);\n\treturn \"ERR\";\n}\n\nexport function maybeGetText(key: string, ...args: any): string {\n\tconst lang = window.platform_info.language;\n\tconst translation = getVal(key, true);\n\tif (translation === null) {\n\t\treturn key;\n\t}\n\tif (lang in translation) {\n\t\treturn vsprintf(translation[lang], args);\n\t}\n\treturn key;\n}\n", "{\"about_me_bio\":{\"en\":\"About me\",\"ro\":\"Despre mine\"},\"accept\":{\"en\":\"Accept\",\"ro\":\"Acceptare\"},\"accepted\":{\"en\":\"Accepted\",\"ro\":\"Acceptat\"},\"acceptedSubs\":{\"en\":\"Accepted solutions\",\"ro\":\"Solu\u021Bii acceptate\"},\"access_control_short\":{\"en\":\"Access\",\"ro\":\"Acces\"},\"acm_icpc_strat\":{\"en\":\"ACM-ICPC style scoring\",\"ro\":\"Scor stil ACM-ICPC\"},\"action\":{\"en\":\"Action\",\"ro\":\"Ac\u021Biune\"},\"actions\":{\"en\":\"Actions\",\"ro\":\"Ac\u021Biuni\"},\"addToPblist\":{\"en\":\"Add to existing problem list (optional)\",\"ro\":\"Ad\u0103ugare la list\u0103 existent\u0103 (op\u021Bional)\"},\"add_donation\":{\"en\":\"Add donation\",\"ro\":\"Ad\u0103ugare dona\u021Bie\"},\"add_editor\":{\"en\":\"Add editor\",\"ro\":\"Ad\u0103ugare editor\"},\"add_tags\":{\"en\":\"Add tags\",\"ro\":\"Ad\u0103ugare etichete\"},\"add_tester\":{\"en\":\"Add tester\",\"ro\":\"Ad\u0103ugare tester\"},\"add_user\":{\"en\":\"Add user\",\"ro\":\"Ad\u0103ugare utilizator\"},\"add_viewer\":{\"en\":\"Add viewer\",\"ro\":\"Ad\u0103ugare vizualizator\"},\"admin\":{\"en\":\"Admin\",\"ro\":\"Administrator\"},\"admins\":{\"en\":\"Admins\",\"ro\":\"Administratori\"},\"advancedFilters\":{\"en\":\"Advanced filters\",\"ro\":\"Filtre avansate\"},\"advancedOptions\":{\"en\":\"Advanced options\",\"ro\":\"Op\u021Biuni avansate\"},\"advanced_filters\":{\"en\":\"Show advanced filters\",\"ro\":\"Afi\u0219are filtre avansate\"},\"aiTranslationWarning\":{\"en\":\"Warning: This statement was translated by an LLM (like ChatGPT). Results might not be fully accurate or faithful to the original statement. Please report any potential errors on our Discord.\",\"ro\":\"Avertisment: Acest enun\u021B a fost tradus de c\u0103tre un LLM (precum ChatGPT). Este probabil ca rezultatele s\u0103 nu fie 100%% corecte sau ca \u00EEn enun\u021Bul original. V\u0103 rug\u0103m raporta\u021Bi eventual erori pe serverul nostru de Discord.\"},\"all_checklists_announcement\":{\"en\":\"View all archive progress reports [on this page](/problem_lists/progress).\",\"ro\":\"Po\u021Bi s\u0103 vezi progresul de rezolvare al arhivei [pe pagina aceasta](/problem_lists/progress).\"},\"all_contests_announcement\":{\"en\":\"You can also view all available contests [on this page](/contests).\",\"ro\":\"Po\u021Bi, de asemenea, s\u0103 vezi toate concursurile disponibile [pe pagina aceasta](/contests).\"},\"all_problems_announcement\":{\"en\":\"You can also view all problems ordered by ID [on this page](/problems).\",\"ro\":\"Po\u021Bi, de asemenea, s\u0103 vezi toate problemele ordonate dup\u0103 ID [pe pagina aceasta](/problems).\"},\"alreadyRegistered\":{\"en\":\"You are already registered in the contest\",\"jump\":{\"en\":\"Go to contest page\",\"ro\":\"Mergi la pagina acestuia\"},\"ro\":\"E\u0219ti deja \u00EEnregistrat \u00EEn concurs\"},\"amount\":{\"en\":\"Amount\",\"ro\":\"Valoare\"},\"announcement\":{\"en\":\"Feel free to join our %s and reach out if you have any suggestions, wish to become a contributor or would like to collaborate with us.\",\"ro\":\"Nu ezita\u021Bi s\u0103 v\u0103 al\u0103tura\u021Bi %s-ului nostru \u0219i s\u0103 ne contacta\u021Bi dac\u0103 ave\u021Bi sugestii, dori\u021Bi s\u0103 deveni\u021Bi un contribuitor sau dori\u021Bi s\u0103 colabora\u021Bi cu noi.\"},\"announcements\":{\"en\":\"Announcements\",\"ro\":\"Anun\u021Buri\"},\"answer_question\":{\"en\":\"Answer question\",\"ro\":\"R\u0103spunde la \u00EEntrebare\"},\"answered_questions\":{\"en\":\"Answered questions\",\"ro\":\"\u00CEntreb\u0103ri r\u0103spunse\"},\"archive\":{\"en\":\"Archive\",\"ro\":\"Arhiv\u0103\"},\"ascending\":{\"en\":\"Ascending Sort\",\"ro\":\"Criteriu Cresc\u0103tor\"},\"ask_question\":{\"en\":\"Ask a question\",\"ro\":\"Pune o \u00EEntrebare\"},\"att_suggest_text\":{\"en\":\"Autocompleting attachment flags with suggested values...\",\"ro\":\"Se autocompleteaz\u0103 propriet\u0103\u021Bile cu valori sugerate...\"},\"attachmentDeleteConfirm\":{\"en\":\"Are you sure you want to delete %d attachments?\",\"ro\":\"E\u0219ti sigur c\u0103 vrei s\u0103 \u0219tergi %d ata\u0219amente?\"},\"attachments\":{\"en\":\"Attachments\",\"ro\":\"Ata\u0219amente\"},\"attemptedProblems\":{\"en\":\"Attempted problems\",\"ro\":\"Probleme \u00EEncercate\"},\"auth\":{\"captcha\":{\"invalid\":{\"en\":\"Invalid CAPTCHA response.\",\"ro\":\"R\u0103spuns CAPTCHA invalid.\"},\"must_solve\":{\"en\":\"You must solve a CAPTCHA test in order to sign up.\",\"ro\":\"Trebuie s\u0103 rezolvi un test CAPTCHA \u00EEnt\u00E2i ca s\u0103 te po\u021Bi \u00EEnregistra.\"},\"title\":{\"en\":\"Please type the digits you see in the picture below\",\"ro\":\"V\u0103 rug\u0103m scrie\u021Bi cifrele pe care le vede\u021Bi \u00EEn imaginea de mai jos\"}},\"forgot_pwd\":{\"en\":\"Forgot password\",\"ro\":\"Parol\u0103 uitat\u0103\"},\"login\":{\"en\":\"Log In\",\"ro\":\"Logare\"},\"logout\":{\"en\":\"Log Out\",\"ro\":\"Log Out\"},\"signup\":{\"en\":\"Sign Up\",\"ro\":\"\u00CEnregistrare\"}},\"authenticate\":{\"en\":\"Log in\",\"ro\":\"Autentificare\"},\"author\":{\"en\":\"Author\",\"ro\":\"Autor\"},\"author_moved\":{\"en\":\"Author credits are now tags.\",\"ro\":\"Creditele autorilor sunt acum etichete.\"},\"backToProfile\":{\"en\":\"Back to profile page\",\"ro\":\"\u00CEnapoi la pagina de profil\"},\"bioPruneConfirmation\":{\"en\":\"Are you sure you want to remove this user's bio?\",\"ro\":\"E\u0219it sigur c\u0103 vrei s\u0103 \u0219tergi bio-ul utilizatorului?\"},\"blog_posts\":{\"en\":\"Posts\",\"ro\":\"Post\u0103ri\"},\"blogpost\":{\"list\":{\"en\":\"Posts\",\"ro\":\"Post\u0103ri\"}},\"boolFlags\":{\"en\":\"Boolean flags\",\"ro\":\"Flag-uri bool\"},\"buckets\":{\"en\":\"Buckets\",\"ro\":\"Bucket-uri\"},\"bulk_update_sources\":{\"en\":\"Bulk update source credits\",\"ro\":\"Actualizare rapid\u0103 sursa problemei\"},\"bulk_update_templ\":{\"en\":\"%s: Problem %%d\",\"ro\":\"%s: Problema %%d\"},\"button\":{\"add\":{\"en\":\"Add\",\"ro\":\"Ad\u0103ugare\"},\"answer\":{\"en\":\"Answer\",\"ro\":\"R\u0103spunde\"},\"cancel\":{\"en\":\"Cancel\",\"ro\":\"Anulare\"},\"create\":{\"en\":\"Create\",\"ro\":\"Creare\"},\"delete\":{\"en\":\"Delete\",\"ro\":\"\u0218tergere\"},\"filter\":{\"en\":\"Filter\",\"ro\":\"Filtrare\"},\"respond\":{\"en\":\"Respond\",\"ro\":\"R\u0103spunde\"},\"select\":{\"en\":\"Select\",\"ro\":\"Selectare\"},\"update\":{\"en\":\"Update\",\"ro\":\"Actualizare\"},\"upload\":{\"en\":\"Upload\",\"ro\":\"\u00CEnc\u0103rcare\"}},\"byDefault\":{\"en\":\"by default\",\"ro\":\"din oficiu\"},\"can_login\":{\"en\":\"Can log in\",\"ro\":\"Se poate autentifica\"},\"cancelled_at\":{\"en\":\"Cancelled at\",\"ro\":\"Anulat la\"},\"changeAvatar\":{\"en\":\"Change avatar source\",\"ro\":\"Schimbare surs\u0103 avatar\"},\"changeAvatarNoDiscord\":{\"en\":\"This option will have no effect until you link your Discord account [using this link](/link/discord)\",\"ro\":\"Aceast\u0103 op\u021Biune nu va avea niciun efect c\u00E2t timp nu asocia\u021Bi contul de Discord [folosind acest link](/link/discord)\"},\"changeAvatarWithDiscord\":{\"en\":\"If Discord is selected, it will use the avatar for the user `%s`.\",\"ro\":\"Dac\u0103 este selectat Discord, acesta va folosi avatarul pentru utilizatorul `%s`.\"},\"changeName\":{\"en\":\"Change name\",\"ro\":\"Schimbare nume\"},\"changeRoles\":{\"en\":\"Change roles\",\"ro\":\"Schimb\u0103 rolurile\"},\"change_name\":{\"en\":\"Force change username\",\"ro\":\"Schimbare for\u021Bat\u0103 username\"},\"checker\":{\"en\":\"Checker\",\"ro\":\"Verificator\"},\"checklist_author_tags\":{\"en\":\"Author tag (even if you are the author)\",\"ro\":\"Etichet\u0103 cu autor (chiar dac\u0103 tu e\u0219ti autorul)\"},\"checklist_contest_required\":{\"en\":\"If problem is/was from a contest, the following are strongly recommended\",\"ro\":\"Dac\u0103 problema este/a fost la un concurs, urm\u0103toarele sunt foarte recomandate\"},\"checklist_md\":{\"en\":\"Markdown statement\",\"ro\":\"Enun\u021B \u00EEn format markdown\"},\"checklist_no_diagnostics\":{\"en\":\"No diagnostic messages (see sidebar)\",\"ro\":\"Niciun mesaj de diagnosticare (vezi bara lateral\u0103)\"},\"checklist_optional\":{\"en\":\"Optional, check if it's required in your case\",\"ro\":\"Op\u021Bionale, verific\u0103 dac\u0103 este necesar \u00EEn cazul t\u0103u\"},\"checklist_other_tags\":{\"en\":\"Other tags\",\"ro\":\"Alte etichete\"},\"checklist_pdf\":{\"en\":\"PDF statement, from contest\",\"ro\":\"Enun\u021B \u00EEn format PDF, de la concurs\"},\"checklist_required\":{\"en\":\"Required items\",\"ro\":\"Elemente necesare\"},\"checklist_solutions\":{\"en\":\"A 100 point solution\",\"ro\":\"O solu\u021Bie de 100 de puncte\"},\"checklist_subtasks\":{\"en\":\"Subtasks (%d currently)\",\"ro\":\"Subtaskuri (%d \u00EEn acest moment)\"},\"checklist_tests\":{\"en\":\"Some tests (%d currently)\",\"ro\":\"C\u00E2teva teste (%d \u00EEn acest moment)\"},\"clearCache\":{\"en\":\"Clear cache\",\"ro\":\"Golire cache\"},\"closeTab\":{\"en\":\"You may close the tab\",\"ro\":\"Pute\u021Bi s\u0103 \u00EEnchide\u021Bi tabul\"},\"code\":{\"en\":\"Code\",\"ro\":\"Cod\"},\"codeSize\":{\"en\":\"Code size\",\"ro\":\"Dimensiunea codului\"},\"code_insert\":{\"en\":\"Insert code\",\"ro\":\"Inserare cod\"},\"communication\":{\"en\":\"Communication\",\"ro\":\"Comunicare\"},\"compileCommand\":{\"en\":\"Compile command\",\"ro\":\"Comand\u0103 compilare\"},\"compileErr\":{\"en\":\"Compile error\",\"ro\":\"Eroare de compilare\"},\"compileMsg\":{\"en\":\"Compilation Message\",\"ro\":\"Mesaj Compilare\"},\"compileTime\":{\"en\":\"Compilation time\",\"ro\":\"Timp compilare\"},\"compilerVersion\":{\"en\":\"Version\",\"ro\":\"Versiune\"},\"compilerVersions\":{\"en\":\"Compiler versions\",\"ro\":\"Versiuni compilatoare\"},\"config\":{\"bannedHotProblems\":{\"en\":\"Problems hidden from Trending tab\",\"ro\":\"Probleme ascunse din panoul Trending\"},\"defaultLang\":{\"en\":\"Default language\",\"ro\":\"Limbaj implicit\"},\"globalMaxMemKB\":{\"en\":\"Global max memory (worker sum usage)\",\"ro\":\"Memorie maxim\u0103 global\u0103 (worker sum usage)\"},\"numWorkers\":{\"en\":\"Number of workers\",\"ro\":\"Num\u0103rul de workeri\"},\"testMaxMemKB\":{\"en\":\"Max memory per test\",\"ro\":\"Memorie maxim\u0103 per test\"},\"title\":{\"en\":\"Site configuration\",\"ro\":\"Configura\u021Bie site\"}},\"confirmContestDelete\":{\"en\":\"Are you sure you want to delete the contest?\",\"ro\":\"E\u0219ti sigur c\u0103 vrei s\u0103 \u0219tergi concursul?\"},\"confirmProblemDelete\":{\"en\":\"Are you sure you want to delete the problem?\",\"ro\":\"E\u0219ti sigur c\u0103 vrei s\u0103 \u0219tergi problema?\"},\"confirmSubReevaluate\":{\"en\":\"Are you sure you want to reevaluate all submissions? It may take a while...\",\"ro\":\"Sigur dore\u0219ti s\u0103 reevaluezi toate submisiile? Poate dura o vreme...\"},\"confirmTestDelete\":{\"en\":\"Are you sure you want to delete the test?\",\"ro\":\"E\u0219ti sigur c\u0103 vrei s\u0103 \u0219tergi testul?\"},\"confirmUserKick\":{\"en\":\"Are you sure you want to kick this user from the contest?\",\"ro\":\"E\u0219ti sigur c\u0103 vrei s\u0103 dai afar\u0103 concurent din concurs?\"},\"confirm_header\":{\"en\":\"Confirm action\",\"ro\":\"Confirmare ac\u021Biune\"},\"confirmedEmail\":{\"en\":\"Email confirmed for user %s\",\"ro\":\"Email confirmat pentru utilizatorul %s\"},\"console\":{\"en\":\"Console Input\",\"ro\":\"Consol\u0103\"},\"consoleInput\":{\"en\":\"Console input\",\"ro\":\"Intrare din consol\u0103\"},\"contents\":{\"en\":\"Contents\",\"ro\":\"Con\u021Binut\"},\"contest\":{\"en\":\"Contest\",\"ro\":\"Concurs\"},\"contestAnnouncement\":{\"en\":\"Announcement\",\"ro\":\"Anun\u021B\"},\"contestID\":{\"en\":\"Contest ID\",\"ro\":\"ID Concurs\"},\"contestInfo\":{\"en\":\"Contest info\",\"ro\":\"Detalii concurs\"},\"contest_before_start\":{\"en\":\"Before start\",\"ro\":\"\u00CEnainte de \u00EEnceput\"},\"contest_edit\":{\"en\":\"Contest Edit\",\"ro\":\"Editare Concurs\"},\"contest_ended\":{\"en\":\"Ended\",\"ro\":\"Finalizat\"},\"contest_index\":{\"all\":{\"en\":\"All contests\",\"ro\":\"Toate concursurile\"},\"create\":{\"en\":\"Create contest\",\"ro\":\"Creare concurs\"},\"official\":{\"en\":\"Official contests\",\"ro\":\"Concursuri oficiale\"},\"personal\":{\"en\":\"My contests\",\"ro\":\"Concursurile mele\"},\"virtual\":{\"en\":\"Virtual contests\",\"ro\":\"Concursuri virtuale\"}},\"contest_info\":{\"en\":\"Contest Info\",\"ro\":\"Detalii Concurs\"},\"contest_no_problems\":{\"en\":\"Contest currently has no associated problems.\",\"ro\":\"Concursul nu are, \u00EEn prezent, probleme aferente.\"},\"contest_problems_participants\":{\"en\":\"Problems are available only for participants while contest is running.\",\"ro\":\"Problemele sunt disponibile doar pentru participan\u021Bi c\u00E2t timp se desf\u0103\u0219oar\u0103 concursul.\"},\"contest_problems_register\":{\"en\":\"Problems will be available once you register.\",\"ro\":\"Problemele vor fi disponibile atunci c\u00E2nd te \u00EEnregistrezi \u00EEn concurs.\"},\"contest_problems_soon\":{\"en\":\"Problems will be available soon.\",\"ro\":\"Problemele vor fi disponibile \u00EEn cur\u00E2nd.\"},\"contest_registrations\":{\"en\":\"Contest Registrations\",\"ro\":\"\u00CEnregistr\u0103ri Concurs\"},\"contest_remaining\":{\"en\":\"remaining\",\"ro\":\"r\u0103mase\"},\"contest_running\":{\"en\":\"Running...\",\"ro\":\"\u00CEn desf\u0103\u0219urare...\"},\"contest_starting_in\":{\"en\":\"Starts in\",\"ro\":\"\u00CEncepe \u00EEn\"},\"contest_timestamp_asked_format\":{\"en\":\"[Asked on] DD/MM/YYYY [at] HH:mm:ss\",\"ro\":\"[\u00CEntrebat pe] DD/MM/YYYY [la] HH:mm:ss\"},\"contest_timestamp_posted_format\":{\"en\":\"[Posted on] DD/MM/YYYY [at] HH:mm:ss\",\"ro\":\"[Creat pe] DD/MM/YYYY [la] HH:mm:ss\"},\"contest_timestamp_responded_format\":{\"en\":\"[Responded on] DD/MM/YYYY [at] HH:mm:ss\",\"ro\":\"[R\u0103spuns pe] DD/MM/YYYY [la] HH:mm:ss\"},\"contest_type\":{\"en\":\"Contest type\",\"official\":{\"en\":\"Official contest\",\"ro\":\"Concurs oficial\"},\"ro\":\"Tip concurs\",\"virtual\":{\"en\":\"Virtual contest\",\"ro\":\"Concurs virtual\"}},\"contest_type_warn\":{\"en\":\"Only admins can create/set official contests. Admins can mark virtual contests as official at a later date.\",\"ro\":\"Numai administratorii pot s\u0103 creeze \u0219i marcheze concursuri de tip oficial. Administratorii pot marca, ulterior, concursurile virtuale drept oficiale.\"},\"contest_user_time\":{\"en\":\"Individual duration\",\"ro\":\"Durat\u0103 individual\u0103\"},\"contests\":{\"en\":\"Contests\",\"ro\":\"Concursuri\"},\"copied\":{\"en\":\"Copied to clipboard\",\"ro\":\"Copiat \u00EEn clipboard\"},\"copy\":{\"en\":\"Copy\",\"ro\":\"Copiere\"},\"correct\":{\"en\":\"correct\",\"ro\":\"corect\"},\"create\":{\"en\":\"Create\",\"ro\":\"Creare\"},\"createBio\":{\"en\":\"Create Bio\",\"ro\":\"Creare Bio\"},\"createContest\":{\"en\":\"Create contest\",\"ro\":\"Creare concurs\"},\"createDefaultStatement\":{\"en\":\"Add default statement\",\"ro\":\"Ad\u0103ugare enun\u021B implicit\"},\"createInvitation\":{\"en\":\"Create invitation (unlimited uses)\",\"ro\":\"Creare invita\u021Bie (utiliz\u0103ri nelimitate)\"},\"createMOSS\":{\"en\":\"Invoke MOSS (ideally after contest end)\",\"ro\":\"Invocare MOSS (preferabil dup\u0103 sf\u00E2r\u0219itul concursului)\"},\"createNestedPbList\":{\"en\":\"Create problem list nested here\",\"ro\":\"Creare list\u0103 probleme imbricat\u0103 aici\"},\"createPb\":{\"en\":\"Create problem\",\"ro\":\"Creare problem\u0103\"},\"createPbList\":{\"en\":\"Create problem list\",\"ro\":\"Creare list\u0103 probleme\"},\"createPost\":{\"en\":\"Create post\",\"ro\":\"Creare postare\"},\"createSingleUseInvitation\":{\"en\":\"Create invitation (single-use)\",\"ro\":\"Creare invita\u021Bie (o singur\u0103 utilizare)\"},\"createSubTask\":{\"en\":\"Create Subtask\",\"ro\":\"Creare Subtask\"},\"createTest\":{\"en\":\"Create Test\",\"ro\":\"Creare Test\"},\"create_announcement\":{\"en\":\"Create announcement\",\"ro\":\"Creare anun\u021B\"},\"create_attachment\":{\"en\":\"Create attachment\",\"ro\":\"Creare ata\u0219ament\"},\"create_edit\":{\"en\":\"Create and Edit\",\"ro\":\"Creare \u0219i Editare\"},\"create_paste\":{\"en\":\"Create paste\",\"ro\":\"Creare paste\"},\"create_simulation\":{\"en\":\"Create simulation contest of list\",\"ro\":\"Creare concurs de simulare a listei\"},\"create_tag\":{\"en\":\"Create tag\",\"ro\":\"Creare etichet\u0103\"},\"created_at\":{\"en\":\"Created at\",\"ro\":\"Creat pe\"},\"created_by\":{\"en\":\"Created by\",\"ro\":\"Creat\u0103 de\"},\"created_problems\":{\"en\":\"My problems\",\"ro\":\"Problemele mele\"},\"credits\":{\"en\":\"Credits\",\"ro\":\"Credite\"},\"currency\":{\"en\":\"Currency\",\"ro\":\"Moned\u0103\"},\"currentUsername\":{\"en\":\"Current username\",\"ro\":\"Nume prezent\"},\"days\":{\"en\":\"%d days\",\"ro\":\"%d zile\"},\"deauthAll\":{\"en\":\"Log out everywhere\",\"ro\":\"Delogare peste tot\"},\"debug_info\":{\"en\":\"Debug information\",\"ro\":\"Informa\u021Bii pentru debugging\"},\"defaultPoints\":{\"en\":\"Points by default\",\"ro\":\"Puncte din oficiu\"},\"delAccConfirmation\":{\"en\":\"Are you sure you want to prune the user?\",\"ro\":\"E\u0219ti sigur c\u0103 vrei s\u0103 \u0219tergi utilizatorul?\"},\"del_paste\":{\"en\":\"Remove paste\",\"ro\":\"\u0218tergere paste\"},\"deleteAccount\":{\"en\":\"Prune User\",\"ro\":\"\u0218tergere Profil\"},\"deleteAttachments\":{\"en\":\"Delete selected attachments\",\"ro\":\"\u0218terge ata\u0219amentele selectate\"},\"deleteContest\":{\"en\":\"Delete contest\",\"ro\":\"\u0218terge concurs\"},\"deleteProblem\":{\"en\":\"Delete problem\",\"ro\":\"\u0218terge problema\"},\"deleteSubTasks\":{\"en\":\"Delete selected Subtasks\",\"ro\":\"\u0218terge Subtaskuri selectate\"},\"deleteTests\":{\"en\":\"Delete selected tests\",\"ro\":\"\u0218terge testele selectate\"},\"desc\":{\"en\":\"Description\",\"ro\":\"Descriere\"},\"desc_link\":{\"en\":\"Download statement\",\"ro\":\"Desc\u0103rcare enun\u021B\"},\"desc_link_post\":{\"en\":\"Download contents\",\"ro\":\"Desc\u0103rcare con\u021Binut\"},\"description\":{\"en\":\"Description\",\"ro\":\"Descriere\"},\"differentPwds\":{\"en\":\"Passwords do not match\",\"ro\":\"Parolele nu se potrivesc\"},\"disabled_signup\":{\"en\":\"Manual signup has been disabled by the administrator\",\"ro\":\"\u00CEnregistrearea manual\u0103 a fost dezactivat\u0103 de c\u0103tre administrator\"},\"discordLink\":{\"en\":\"Discord link\",\"ro\":\"Asociere Discord\"},\"discordLinkStatus\":{\"en\":\"is linked with the following Discord account\",\"ro\":\"este asociat cu urm\u0103torul cont de Discord\"},\"diskSize\":{\"en\":\"Size on disk\",\"ro\":\"Dimensiune pe disc\"},\"displayLang\":{\"en\":\"Display language\",\"ro\":\"Limb\u0103 afi\u0219aj\"},\"donate\":{\"en\":\"Donate\",\"front_page_par\":{\"en\":\"If you enjoy using Kilonova, \\u003ca href=\\\"/donate\\\"\\u003eplease consider leaving a small donation.\\u003c/a\\u003e\",\"ro\":\"Dac\u0103 \u00EE\u021Bi place s\u0103 utilizezi Kilonova, \\u003ca href=\\\"/donate\\\"\\u003ete rug\u0103m s\u0103 iei \u00EEn considerare l\u0103sarea unei mici dona\u021Bii.\\u003c/a\\u003e\"},\"ro\":\"Doneaz\u0103\"},\"donate_bmac_disclaimer\":{\"en\":\"(alternative)\",\"ro\":\"(alternativ\u0103)\"},\"donate_cancelled\":{\"en\":\"Transaction was cancelled, but we thank you for the thought!\",\"ro\":\"Tranzac\u021Bia a fost anulat\u0103, dar v\u0103 mul\u021Bumim pentru g\u00E2ndul acordat!\"},\"donate_par\":{\"en\":\"If you enjoy using Kilonova, please consider leaving a small donation to support server consts and future development of the platform!\",\"ro\":\"Dac\u0103 \u00EE\u021Bi place s\u0103 utilizezi Kilonova, te rug\u0103m s\u0103 iei \u00EEn considerare l\u0103sarea unei mici dona\u021Bii pentru a sus\u021Bine costurile serverelor \u0219i dezvoltarea viitoare a platformei!\"},\"donate_paypal_disclaimer\":{\"en\":\"(for recurring donations)\",\"ro\":\"(pentru dona\u021Bii recurente)\"},\"donate_stripe_disclaimer\":{\"en\":\"(recommended)\",\"ro\":\"(recomandat)\"},\"donate_success\":{\"en\":\"Thank you for supporting the platform!\",\"ro\":\"V\u0103 mul\u021Bumim pentru sus\u021Binerea acordat\u0103!\"},\"donation_method\":{\"en\":\"Donation method\",\"ro\":\"Metod\u0103 donare\"},\"donation_methods\":{\"en\":\"Donation methods\",\"ro\":\"Metode prin care pute\u021Bi dona\"},\"donation_time\":{\"en\":\"Donation time\",\"ro\":\"Momentul don\u0103rii\"},\"donation_type\":{\"en\":\"Donation type\",\"ro\":\"Tip donare\"},\"donations\":{\"en\":\"Donations\",\"ro\":\"Dona\u021Bii\"},\"dontCreate\":{\"en\":\"Will not create\",\"ro\":\"Nu se va crea\"},\"download\":{\"en\":\"Download\",\"ro\":\"Desc\u0103rcare\"},\"downloadArchive\":{\"en\":\"Download tests\",\"ro\":\"Desc\u0103rcare teste\"},\"duration\":{\"en\":\"Total duration\",\"ro\":\"Durat\u0103 total\u0103\"},\"edit\":{\"en\":\"Edit\",\"ro\":\"Editare\"},\"editBio\":{\"en\":\"Edit Bio\",\"ro\":\"Editare Bio\"},\"edit_answer\":{\"en\":\"Edit answer\",\"ro\":\"Editare r\u0103spuns\"},\"edit_attachment\":{\"en\":\"Edit attachment\",\"ro\":\"Editare ata\u0219ament\"},\"editor\":{\"en\":\"Editor\",\"ro\":\"Editor\"},\"editors\":{\"en\":\"Editors\",\"ro\":\"Editori\"},\"email\":{\"en\":\"Email\",\"resent\":{\"en\":\"Resent email\",\"ro\":\"Email retrimis\"},\"ro\":\"Email\",\"verified\":{\"en\":\"Verified Email\",\"ro\":\"Email Verificat\"}},\"emailConfirm\":{\"en\":\"Verified Email\",\"ro\":\"Email Verificat\"},\"emptyTitle\":{\"en\":\"Empty title\",\"ro\":\"Titlu gol\"},\"enable_freeze\":{\"en\":\"Freeze leaderboards\",\"ro\":\"\u00CEnghe\u021Bare clasament\"},\"endTime\":{\"en\":\"End time\",\"ro\":\"Or\u0103 de finalizare\"},\"end_sub_confirmation\":{\"en\":\"Are you sure you want to mark this subscription as cancelled?\",\"ro\":\"E\u0219ti sigur c\u0103 vrei s\u0103 marchezi abonamentul drept anulat?\"},\"error\":{\"message\":{\"en\":\"That's an error\",\"ro\":\"Asta-i o eroare!\"}},\"errors\":{\"problem\":{\"hidden\":{\"en\":\"You are not allowed to view this problem!\",\"ro\":\"Nu ave\u021Bi dreptul s\u0103 accesa\u021Bi problema!\"},\"notfound\":{\"en\":\"Problem does not exist\",\"ro\":\"Problema nu exist\u0103\"}},\"user\":{\"authed\":{\"en\":\"You must be logged in to view this!\",\"ro\":\"Trebuie s\u0103 fii autentificat pentru a putea accesa asta!\"}}},\"evaluated\":{\"en\":\"Evaluated\",\"ro\":\"Evaluat\"},\"evaluating\":{\"en\":\"Evaluating...\",\"ro\":\"\u00CEn evaluare...\"},\"evictBucket\":{\"en\":\"Run eviction now\",\"ro\":\"Executare cur\u0103\u021Bare acum\"},\"exec\":{\"en\":\"Exec\",\"ro\":\"Exec\"},\"existingVariants\":{\"en\":\"Existing variants\",\"ro\":\"Variante existente\"},\"experimentalZone\":{\"en\":\"Experimental zone\",\"ro\":\"Zona experimentelor\"},\"expired\":{\"en\":\"Expired\",\"ro\":\"Expirat\"},\"expiredInvite\":{\"en\":\"Unfortunately, the invitation has expired. You have to get access to a new one to join the contest.\",\"ro\":\"Din p\u0103cate, invita\u021Bia a expirat. Trebuie s\u0103 faci rost de alta pentru a participa \u00EEn concurs.\"},\"expires_at\":{\"en\":\"Expires at\",\"ro\":\"Expir\u0103 pe\"},\"external_resources\":{\"en\":\"External resources\",\"ro\":\"Resurse externe\"},\"featured_checklist\":{\"en\":\"Promoted checklist page\",\"ro\":\"Pagin\u0103 progres promovat\u0103\"},\"feedbackCallToArms\":{\"en\":\"Your voice is valuable. Please [respond to a few simple questions](%s) to improve the platform. Shouldn't take more than 2 minutes :)\",\"ro\":\"Vocea ta este important\u0103. Te rug\u0103m [s\u0103 r\u0103spunzi la ni\u0219te \u00EEntreb\u0103ri](%s) simple pentru a face platforma mai bun\u0103. N-ar trebui s\u0103 ia mai mult de 2 minute :)\"},\"feedbackHeader\":{\"en\":\"Help us with some feedback!\",\"ro\":\"Ajut\u0103-ne cu ni\u0219te feedback!\"},\"fetch\":{\"en\":\"Fetch data\",\"ro\":\"Filtrare\"},\"file\":{\"en\":\"File\",\"ro\":\"Fi\u0219ier\"},\"filterBar\":{\"en\":\"filter bar\",\"ro\":\"bara de filtrare\"},\"filterLink\":{\"en\":\"Copy filter link\",\"ro\":\"Copiere link filtre\"},\"filter_tags\":{\"en\":\"Filter by tags\",\"ro\":\"Filtrare dup\u0103 etichete\"},\"filters\":{\"en\":\"Filters\",\"ro\":\"Filtre\"},\"finalScore\":{\"en\":\"Score for submission #%d: \",\"ro\":\"Scor submisie #%d: \"},\"finished\":{\"en\":\"Finished\",\"ro\":\"Finalizat\"},\"finishedEval\":{\"en\":\"Submission evaluated\",\"ro\":\"Evaluare finalizat\u0103\"},\"forgot_pwd_announcement\":{\"en\":\"Forgot password? Go \\u003ca href=\\\"/forgot_pwd\\\"\\u003eon this page\\u003c/a\\u003e to recover it.\",\"ro\":\"Parol\u0103 uitat\u0103? Mergi \\u003ca href=\\\"/forgot_pwd\\\"\\u003epe pagina aceasta\\u003c/a\\u003e pentru a o recupera.\"},\"freeze_time\":{\"en\":\"Freeze moment\",\"ro\":\"Momentul \u00EEnghe\u021B\u0103rii\"},\"from_sub\":{\"en\":\"from\",\"ro\":\"din\"},\"frontPage\":{\"en\":\"Front page\",\"ro\":\"Pagina principal\u0103\"},\"future_contests\":{\"en\":\"Future contests\",\"ro\":\"Concursuri viitoare\"},\"gen_all_submissions\":{\"en\":\"Include ALL submissions\",\"ro\":\"Include TOATE submisiile\"},\"gen_checker_warning\":{\"en\":\"NOTE: Problem uses a custom checker program. It's likely that the output file won't have proper answers.\",\"ro\":\"NOTE: Problema folose\u0219te un program de verificare. Este posibil ca fi\u0219ierul de ie\u0219ire s\u0103 nu aib\u0103 r\u0103spunsurile potrivite.\"},\"gen_details\":{\"en\":\"Details (limits, credits, problem name, etc.)\",\"ro\":\"Detalii (limite, credite, nume problem\u0103, etc.)\"},\"gen_editors\":{\"en\":\"Include editor names\",\"ro\":\"Include numele editorilor\"},\"gen_submissions\":{\"en\":\"Include editor submissions\",\"ro\":\"Include submisiile editorilor\"},\"gen_tags\":{\"en\":\"Include tags\",\"ro\":\"Include etichete\"},\"gen_title\":{\"en\":\"Select what to include in problem archive\",\"ro\":\"Selecteaz\u0103 ce s\u0103 fie inclus \u00EEn arhiva problemei\"},\"general\":{\"en\":\"General\",\"ro\":\"General\"},\"generalStats\":{\"en\":\"General statistics\",\"ro\":\"Statistici generale\"},\"generated_acc\":{\"en\":\"Generated account\",\"ro\":\"Cont generat\"},\"glossary\":{\"en\":\"Glossary\",\"ro\":\"Glosar\"},\"go_to_communication\":{\"en\":\"Go to communication panel\",\"ro\":\"Mergi la panoul de comunicare\"},\"go_to_paste\":{\"en\":\"Go to paste\",\"ro\":\"Accesa\u021Bi-l\"},\"header\":{\"contest\":{\"access_control\":{\"en\":\"Contest access control\",\"ro\":\"Control acces concurs\"},\"create_pblist\":{\"en\":\"Create problem list from contest problems\",\"ro\":\"Creare list\u0103 probleme din problemele concursului\"},\"edit_problems\":{\"en\":\"Edit Contest Problems\",\"ro\":\"Editare Probleme Concurs\"},\"force_register\":{\"en\":\"Admin: force register user in contest\",\"ro\":\"Admin: \u00EEnregistrare for\u021Bat\u0103 utilizator \u00EEn concurs\"},\"general\":{\"en\":\"Contest Information\",\"ro\":\"Informa\u021Bii Concurs\"},\"invitations\":{\"en\":\"Manage invitations\",\"ro\":\"Administrare invita\u021Bii\"},\"leaderboard\":{\"en\":\"Leaderboard settings\",\"ro\":\"Set\u0103ri clasament\"},\"limits\":{\"en\":\"Contestant Limits\",\"ro\":\"Limite Concuren\u021Bi\"},\"main\":{\"en\":\"Update contest\",\"ro\":\"Actualizare concurs\"},\"moss\":{\"en\":\"Experimental: run MOSS plagiarism checker\",\"ro\":\"Experimental: ruleaz\u0103 verificatorul MOSS pentru plagiat\"}},\"edit\":{\"access_control\":{\"en\":\"Access control\",\"ro\":\"Control acces\"},\"attachment_create\":{\"en\":\"Add Attachment\",\"ro\":\"Ad\u0103ugare Ata\u0219ament\"},\"attachment_history\":{\"en\":\"Last updates\",\"ro\":\"Ultimele actualiz\u0103ri\"},\"attachments\":{\"en\":\"Edit Attachments\",\"ro\":\"Editare Ata\u0219amente\"},\"description\":{\"en\":\"Edit Description (Markdown)\",\"ro\":\"Editare Descriere (Markdown)\"},\"index\":{\"en\":\"Edit Problem Information\",\"ro\":\"Editare Informa\u021Bii Problem\u0103\"},\"subtask\":{\"en\":\"Update Subtasks\",\"ro\":\"Actualizare Subtasks\"},\"subtask_add\":{\"en\":\"Create Subtask\",\"ro\":\"Creare Subtask\"},\"subtask_edit\":{\"en\":\"Edit Subtask #%d\",\"ro\":\"Editare Subtask #%d\"}},\"invitation\":{\"en\":\"Invitation to participate in \\u003ccode\\u003e%s\\u003c/code\\u003e\",\"from\":{\"en\":\"from \\u003ca href=\\\"/profile/%s\\\"\\u003e%[1]s\\u003c/a\\u003e\",\"ro\":\"de la \\u003ca href=\\\"/profile/%s\\\"\\u003e%[1]s\\u003c/a\\u003e\"},\"ro\":\"Invita\u021Bie pentru participarea \u00EEn \\u003ccode\\u003e%s\\u003c/code\\u003e\"},\"past_submissions\":{\"en\":\"Past submissions\",\"ro\":\"Submisii anterioare\"},\"problem_archive\":{\"en\":\"Download data archive for\",\"ro\":\"Desc\u0103rcare arhiv\u0103 date pentru \"},\"problem_statistics\":{\"en\":\"Statistics for \",\"ro\":\"Statistici pentru \"}},\"hide\":{\"en\":\"Hide\",\"ro\":\"Ascunde\"},\"hint\":{\"edit\":{\"description_save\":{\"en\":\"Hint! You can use Ctrl+S to quickly save the text.\",\"ro\":\"Sfat util! Po\u021Bi folosi Ctrl+S ca s\u0103 salvezi rapid textul.\"}}},\"hot_problems\":{\"en\":\"Trending problems\",\"ro\":\"Probleme trending\"},\"icpc_num_solved\":{\"en\":\"# Solved\",\"ro\":\"# Rezolvate\"},\"icpc_submission_penalty\":{\"en\":\"ICPC penalty per attempt\",\"ro\":\"Penalizare ICPC per \u00EEncercare\"},\"id\":{\"en\":\"ID\",\"ro\":\"ID\"},\"importProblem\":{\"en\":\"Import problem from archive\",\"ro\":\"Importare problem\u0103 din arhiv\u0103\"},\"importProblemWarn\":{\"en\":\"A stub problem will be created and will have the file loaded as test archive.\",\"ro\":\"A problem\u0103 temporar\u0103 va fi creat\u0103 \u0219i va \u00EEnc\u0103rca fi\u0219ierul drept arhiv\u0103 de test.\"},\"individualTests\":{\"en\":\"Individual tests\",\"ro\":\"Teste individuale\"},\"individual_tests\":{\"en\":\"Download individual tests\",\"ro\":\"Desc\u0103rcare teste individuale\"},\"info\":{\"en\":\"Summary\",\"ro\":\"Informa\u021Bii\"},\"input\":{\"en\":\"Input\",\"ro\":\"Intrare\"},\"intFlags\":{\"en\":\"Number flags\",\"ro\":\"Flag-uri numere\"},\"invalid_file\":{\"en\":\"Invalid file\",\"ro\":\"Fi\u0219ier invalid\"},\"invalidate\":{\"en\":\"Invalidate\",\"ro\":\"Invalidare\"},\"invisible\":{\"en\":\"Invisible\",\"ro\":\"Invizibil\"},\"inviteManyRedeems\":{\"en\":\"The invite was redeemed for a maximum number of times.\",\"ro\":\"Invita\u021Bia a fost utilizat\u0103 de un num\u0103r maxim de ori.\"},\"inviteUses\":{\"en\":\"Used / Total\",\"ro\":\"Utilizat / Total\"},\"kick_user\":{\"en\":\"Kick\",\"ro\":\"Exclude\"},\"language\":{\"en\":\"Language\",\"ro\":\"Limbaj\"},\"languageName\":{\"en\":\"Language\",\"ro\":\"Limbaj\"},\"last_updated_at\":{\"en\":\"Last updated at\",\"ro\":\"Actualizat la\"},\"last_updated_by\":{\"en\":\"Last updated by\",\"ro\":\"Actualizat de\"},\"latestPbs\":{\"en\":\"Latest published problems\",\"ro\":\"Ultimele probleme publicate\"},\"latest_problems_announcement\":{\"en\":\"You can view a longer list [on this page](/problems?ordering=published_at\\u0026descending=true).\",\"ro\":\"Po\u021Bi s\u0103 vezi o list\u0103 mai lung\u0103 [pe pagina aceasta](/problems?ordering=published_at\\u0026descending=true).\"},\"leaderboard\":{\"classic\":{\"en\":\"Classic (IOI)\",\"ro\":\"Clasic (IOI)\"},\"en\":\"Leaderboard\",\"icpc\":{\"en\":\"ACM-ICPC\",\"ro\":\"ACM-ICPC\"},\"ro\":\"Clasament\",\"style\":{\"en\":\"Leaderboard type\",\"ro\":\"Tip clasament\"}},\"lifetime_donation_cnt\":{\"en\":\"Total donated\",\"ro\":\"Donat \u00EEn total\"},\"list\":{\"en\":\"List\",\"ro\":\"List\u0103\",\"update\":{\"en\":\"Update List\",\"ro\":\"Actualizare List\u0103\"},\"user_view_info\":{\"en\":\"Viewing progress for\",\"ro\":\"Se afi\u0219eaz\u0103 progresul pentru\"},\"view_as_user\":{\"en\":\"View another user's progress\",\"ro\":\"Vezi progresul altui utilizator\"},\"view_checklist\":{\"en\":\"View progress\",\"ro\":\"Vizualizare progres\"},\"view_list\":{\"en\":\"View as list\",\"ro\":\"Vizualizare list\u0103\"}},\"list_parent_id\":{\"en\":\"Parent List ID (for automatic nesting, optional)\",\"ro\":\"ID list\u0103 p\u0103rinte (pentru imbricare automat\u0103, op\u021Bional)\"},\"lists\":{\"en\":\"Lists\",\"ro\":\"Liste\"},\"loading\":{\"en\":\"Loading...\",\"ro\":\"Se \u00EEncarc\u0103...\"},\"logDate\":{\"en\":\"Log time\",\"ro\":\"Ora ac\u021Biunii\"},\"loginReminder\":{\"en\":\"Already have an account? \\u003ca href=\\\"/login\\\"\\u003eLog in\\u003c/a\\u003e!\",\"ro\":\"Ai deja cont? \\u003ca href=\\\"/login\\\"\\u003eLogheaz\u0103-te\\u003c/a\\u003e!\"},\"mail\":{\"subject\":{\"generated\":{\"en\":\"Kilonova login details\",\"ro\":\"Date de autentificare cont Kilonova\"},\"password_recovery\":{\"en\":\"Recover Kilonova account password\",\"ro\":\"Recuperare parol\u0103 cont Kilonova\"},\"verification\":{\"en\":\"Verify your email address\",\"ro\":\"Verific\u0103-\u021Bi adresa de email\"}}},\"makeAdmin\":{\"en\":\"Make Admin\",\"ro\":\"F\u0103 Administrator\"},\"makeCode\":{\"en\":\"Make code\",\"ro\":\"F\u0103 codul\"},\"makeProposer\":{\"en\":\"Make Proposer\",\"ro\":\"F\u0103 Propun\u0103tor\"},\"makeSubs\":{\"en\":\"Make submissions implicitly\",\"ro\":\"F\u0103 submisiile implicit\"},\"manageUser\":{\"en\":\"Manage user\",\"ro\":\"Administrare utilizator\"},\"manage_sessions\":{\"en\":\"Manage sessions\",\"ro\":\"Administrare sesiuni\"},\"manage_sessions_btn\":{\"en\":\"Manage sessions (experimental)\",\"ro\":\"Administrare sesiuni (experimental)\"},\"manyAttemptedProblems\":{\"en\":\"%d attempted problems\",\"ro\":\"%d probleme \u00EEncercate\"},\"manyResults\":{\"en\":\"results\",\"ro\":\"de rezultate\"},\"manySolvedProblems\":{\"en\":\"%d solved problems\",\"ro\":\"%d probleme rezolvate\"},\"maxBucketSize\":{\"en\":\"Maximum eviction size\",\"ro\":\"Dimensiune maxim\u0103 pentru evic\u021Bie\"},\"maxBucketTTL\":{\"en\":\"Maximum bucket TTL\",\"ro\":\"TTL maxim per bucket\"},\"maxSubs\":{\"en\":\"Maximum submission count (per problem)\",\"ro\":\"Num\u0103r limit\u0103 submisii (pe problem\u0103)\"},\"max_submission_strat\":{\"en\":\"Maximum score submission (default)\",\"ro\":\"Submisia de scor maxim (implicit)\"},\"mdCacheWarmup\":{\"en\":\"Warm up markdown statement cache\",\"ro\":\"Generare cache enun\u021Buri markdown\"},\"memory\":{\"en\":\"Memory\",\"ro\":\"Memorie\"},\"memoryLeaderboard\":{\"en\":\"Lowest memory leaderboard\",\"ro\":\"Clasament submisii de memorie minim\u0103\"},\"memoryLimit\":{\"en\":\"Memory limit\",\"ro\":\"Limit\u0103 de memorie\"},\"metrics\":{\"en\":\"Metrics\",\"ro\":\"Metrici\"},\"minutes\":{\"en\":\"minutes\",\"ro\":\"minute\"},\"misconfigured_modal\":{\"en\":\"This modal was misconfigured. Please report this bug.\",\"ro\":\"Acest modal a fost configurat gresit. V\u0103 rug\u0103m s\u0103 raporta\u021Bi acest bug.\"},\"must_change_uname\":{\"en\":\"Is required to change username\",\"ro\":\"Este obligat s\u0103 schimbe username-ul\"},\"name\":{\"en\":\"Name\",\"ro\":\"Nume\"},\"nameFilter\":{\"en\":\"Filter by name\",\"ro\":\"Filtrare dup\u0103 nume\"},\"name_or_id\":{\"en\":\"Name or ID\",\"ro\":\"Nume sau ID\"},\"new\":{\"en\":\"New!\",\"ro\":\"Nou!\"},\"newEmail\":{\"en\":\"New email\",\"ro\":\"Email nou\"},\"newPwd\":{\"en\":\"New password\",\"ro\":\"Parol\u0103 nou\u0103\"},\"newPwdConfirm\":{\"en\":\"Confirm new password\",\"ro\":\"Confirmare parol\u0103 nou\u0103\"},\"newUsername\":{\"en\":\"New username\",\"ro\":\"Nume nou\"},\"new_announcement\":{\"en\":\"New announcement posted\",\"ro\":\"Anun\u021B nou postat\"},\"new_format\":{\"en\":\"New format\",\"ro\":\"Format nou\"},\"new_question\":{\"en\":\"New question asked\",\"ro\":\"\u00CEntrebare nou\u0103 pus\u0103\"},\"new_response\":{\"en\":\"New question response\",\"ro\":\"Nou r\u0103spuns la \u00EEntrebare\"},\"no\":{\"en\":\"No\",\"ro\":\"Nu\"},\"noAnnouncements\":{\"en\":\"No announcements posted\",\"ro\":\"Niciun anun\u021B f\u0103cut\"},\"noAttachments\":{\"en\":\"There are no attachments for the problem\",\"ro\":\"Nu exist\u0103 niciun ata\u0219ament asociat problemei\"},\"noContests\":{\"en\":\"No contests are available at this time\",\"ro\":\"Niciun concurs nu este disponibil momentan\"},\"noDiscordLink\":{\"en\":\"No Discord connection has been made.\",\"ro\":\"Nu a fost f\u0103cut\u0103 nicio asociere cu vreun cont de Discord.\"},\"noFeaturedChecklist\":{\"en\":\"No checklist was marked for presentation.\",\"ro\":\"Niciun checklist marcat pentru prezentare.\"},\"noFiles\":{\"en\":\"No files selected\",\"ro\":\"Niciun fi\u0219ier specificat\"},\"noInvitations\":{\"en\":\"No invitations found\",\"ro\":\"Nicio invita\u021Bie g\u0103sit\u0103\"},\"noMOSSHistory\":{\"en\":\"No past MOSS invocations\",\"ro\":\"Nicio invocare anterioar\u0103 MOSS\"},\"noPbFound\":{\"en\":\"No problem found\",\"ro\":\"Nicio problem\u0103 g\u0103sit\u0103\"},\"noPostFound\":{\"en\":\"No post found\",\"ro\":\"Nicio postare g\u0103sit\u0103\"},\"noQuestions\":{\"en\":\"No questions asked\",\"ro\":\"Nicio \u00EEntrebare pus\u0103\"},\"noSub\":{\"en\":\"No submissions\",\"ro\":\"Nicio submisie\"},\"noSubFound\":{\"en\":\"No submission found\",\"ro\":\"Nicio submisie g\u0103sit\u0103\"},\"noSubTasks\":{\"en\":\"There are no Subtasks, tests will be scored individually\",\"ro\":\"Nu exist\u0103 niciun Subtask, testele se vor evalua individual\"},\"noSyntaxHighlight\":{\"en\":\"Syntax highlighting is not available for this source code.\",\"ro\":\"Syntax highlighting nu este disponibil pentru acest cod surs\u0103.\"},\"noTests\":{\"en\":\"There aren't any tests, it would be nice to create one :)\",\"ro\":\"Nu exist\u0103 niciun test, ar fi bine s\u0103 creezi unul :)\"},\"noTestsError\":{\"en\":\"The problem doesn't have any tests.\",\"ro\":\"Problema nu are niciun test.\"},\"noUserFound\":{\"en\":\"No user found\",\"ro\":\"Niciun utilizator g\u0103sit\"},\"no_code\":{\"en\":\"No code provided\",\"ro\":\"Nu ai specificat niciun cod\"},\"no_file\":{\"en\":\"No file provided\",\"ro\":\"Nu ai specificat niciun fi\u0219ier\"},\"no_notices\":{\"en\":\"No notices, problem seems well-configured.\",\"ro\":\"Nicio \u00EEn\u0219tiin\u021Bare, problema pare bine configurat\u0103.\"},\"no_resources\":{\"en\":\"No resources added\",\"ro\":\"Nu exist\u0103 resurse asociate\"},\"no_selected_tags\":{\"en\":\"No selected tags.\",\"ro\":\"Nicio etichet\u0103 selectat\u0103.\"},\"no_tags\":{\"en\":\"No tag found\",\"ro\":\"Nicio etichet\u0103 g\u0103sit\u0103\"},\"no_users\":{\"en\":\"No users\",\"ro\":\"Niciun utilizator\"},\"notCopied\":{\"en\":\"Couldn't copy to clipboard.\",\"ro\":\"Nu s-a putut copia \u00EEn clipboard.\"},\"not_answered\":{\"en\":\"Not answered\",\"ro\":\"F\u0103r\u0103 r\u0103spuns\"},\"not_started\":{\"en\":\"Not started\",\"ro\":\"N-a \u00EEnceput\"},\"nthSubTask\":{\"en\":\"Subtask #%d\",\"ro\":\"Subtaskul #%d\"},\"nthTest\":{\"en\":\"Test #%d\",\"ro\":\"Testul #%d\"},\"numUsersAttempted\":{\"en\":\"Attempted by: %d\",\"ro\":\"\u00CEncercat\u0103 de: %d\"},\"numUsersSolved\":{\"en\":\"Solved by: %d\",\"ro\":\"Rezolvat\u0103 de: %d\"},\"num_att_solved\":{\"en\":\"Num. Solved / Attempted\",\"ro\":\"Nr. Rezolvat / \u00CEncercat\"},\"num_problems\":{\"en\":\"%d problems\",\"ro\":\"%d probleme\"},\"num_registrations\":{\"en\":\"%d registrations\",\"ro\":\"%d \u00EEnregistr\u0103ri\"},\"num_solved\":{\"en\":\"%d / %d solved\",\"ro\":\"%d / %d rezolvate\"},\"objectCount\":{\"en\":\"Object count\",\"ro\":\"Num\u0103rul de obiecte\"},\"official\":{\"en\":\"Official\",\"ro\":\"Oficial\"},\"oldSubs\":{\"en\":\"Your submissions\",\"ro\":\"Submisiile tale\"},\"oneAttachmentDeleteConfirm\":{\"en\":\"Are you sure you want to delete the attachment?\",\"ro\":\"E\u0219ti sigur c\u0103 vrei s\u0103 \u0219tergi ata\u0219amentul?\"},\"oneAttemptedProblem\":{\"en\":\"One attempted problem:\",\"ro\":\"O problem\u0103 \u00EEncercat\u0103:\"},\"oneResult\":{\"en\":\"One result\",\"ro\":\"Un rezultat\"},\"oneSolvedProblem\":{\"en\":\"One solved problem:\",\"ro\":\"O problem\u0103 rezolvat\u0103:\"},\"oneSubtaskDeleteConfirm\":{\"en\":\"Are you sure you want to delete the subtask?\",\"ro\":\"E\u0219ti sigur c\u0103 vrei s\u0103 \u0219tergi subtaskul?\"},\"oneTestDeleteConfirm\":{\"en\":\"Are you sure you want to delete the test?\",\"ro\":\"E\u0219ti sigur c\u0103 vrei s\u0103 \u0219tergi testul?\"},\"organisedBy\":{\"en\":\"Organised by\",\"ro\":\"Organizat de\"},\"other\":{\"en\":\"Other\",\"ro\":\"Altceva\"},\"otherInfo\":{\"en\":\"Other information\",\"ro\":\"Alte informa\u021Bii\"},\"output\":{\"en\":\"Output\",\"ro\":\"Ie\u0219ire\"},\"page\":{\"en\":\"Page\",\"ro\":\"Pagin\u0103\"},\"panel\":{\"admin\":{\"en\":\"Admin Panel\",\"ro\":\"Panou Admin\"},\"audit_log\":{\"en\":\"Audit Logs\",\"ro\":\"Registru ac\u021Biuni\"},\"debug\":{\"en\":\"Debugging Panel\",\"ro\":\"Panou Debugging\"},\"grader\":{\"en\":\"Grader Panel\",\"ro\":\"Panou Grader\"},\"proposer\":{\"en\":\"Proposer Panel\",\"ro\":\"Panou Propun\u0103tor\"}},\"parent_list\":{\"en\":\"[Parent List]\",\"ro\":\"[List\u0103 p\u0103rinte]\"},\"participants\":{\"all\":{\"en\":\"All participants\",\"ro\":\"To\u021Bi participan\u021Bii\"},\"label\":{\"en\":\"Filter participants\",\"ro\":\"Filtrare participan\u021Bi\"},\"official\":{\"en\":\"Official participants\",\"ro\":\"Participan\u021Bii oficiali\"},\"unofficial\":{\"en\":\"Unofficial participants\",\"ro\":\"Participan\u021Bii neoficiali\"}},\"password\":{\"en\":\"Password\",\"ro\":\"Parol\u0103\"},\"passwordCheck\":{\"en\":\"Check Password\",\"ro\":\"Verificare Parol\u0103\"},\"past_contests\":{\"en\":\"Past contests\",\"ro\":\"Concursuri anterioare\"},\"past_donations\":{\"en\":\"Past donations\",\"ro\":\"Dona\u021Bii anterioare\"},\"pasteDeleteConfirm\":{\"en\":\"Are you sure you want to delete this paste?\",\"ro\":\"E\u0219ti sigur c\u0103 vrei s\u0103 \u0219tergi acest paste?\"},\"paste_title\":{\"en\":\"Paste\",\"ro\":\"Paste-ul\"},\"paste_url_copied\":{\"en\":\"Paste URL copied to clipboard.\",\"ro\":\"URL-ul paste-ului a fost copiat \u00EEn clipboard.\"},\"pblistDeleteConfirm\":{\"en\":\"Are you sure you want to delete this list?\",\"ro\":\"E\u0219ti sigur c\u0103 vrei s\u0103 \u0219tergi aceast\u0103 list\u0103?\"},\"pblist_id\":{\"en\":\"Problem List ID\",\"ro\":\"ID List\u0103 Probleme\"},\"pblist_submissions\":{\"en\":\"View submissions\",\"ro\":\"Vizualizare submisii\"},\"pbs\":{\"en\":\"Problems (IDs separated by a comma)\",\"ro\":\"Probleme (ID-uri separate prin virgul\u0103)\"},\"penalty\":{\"en\":\"Penalty\",\"ro\":\"Penalizare\"},\"per_month\":{\"en\":\"/ month\",\"ro\":\"/ lun\u0103\"},\"per_user_time\":{\"en\":\"Individual user time (USACO-style)\",\"ro\":\"Timp individual (stil USACO)\"},\"per_user_time_warning\":{\"en\":\"Warning: setting the individual user time parameter to a nonzero value will turn the contest into an USACO-style contest.\",\"ro\":\"Warning: setarea parametrului pentru timp individual la o valoare nenul\u0103 va transforma concursul \u00EEn unul tip USACO.\"},\"per_year\":{\"en\":\"/ year\",\"ro\":\"/ an\"},\"pinned_lists\":{\"en\":\"Highlighted lists\",\"ro\":\"Liste eviden\u021Biate\"},\"points\":{\"en\":\"points\",\"ro\":\"puncte\"},\"polygonArchiveWarn\":{\"en\":\"Note for Polygon archives: only the checker, solutions and the \\u003ccode\\u003etests\\u003c/code\\u003e testset data is taken into consideration. The platform does a best effort attempt to find and match groups and test scores, if supplied, however it likely won't be perfect (experimental feature, send message to admin for feedback). In ICPC mode, groups are ignored. Group dependencies are not chained, you need to list all of them explicitly. IMPORTANT! ONLY Full, Linux packages are oficially supported.\",\"ro\":\"Important pentru arhivele Polygon: doar checker-ul, sursele oficiale \u0219i testset-ul \\u003ccode\\u003etests\\u003c/code\\u003e este luat \u00EEn considerare. Platforma va \u00EEncerca s\u0103 deduc\u0103 grupurile (subtaskurile) \u0219i scorurile pe teste, \u00EEns\u0103 cel mai probabil nu va fi perfect (feature experimental, trimite\u021Bi mesaj adminului pentru feedback). \u00CEn mod ICPC, groups sunt ignorate. Dependencies pentru grupuri nu sunt \u00EEnl\u0103n\u021Buite, trebuie selectate toate explicit. IMPORTANT! DOAR package-urile de tipul Full, Linux sunt suportate oficial.\"},\"position\":{\"en\":\"Position\",\"ro\":\"Pozi\u021Bie\"},\"post\":{\"nav\":{\"attachments\":{\"en\":\"Attachments\",\"ro\":\"Ata\u0219amente\"},\"edit\":{\"en\":\"Update\",\"ro\":\"Editare\"},\"view\":{\"en\":\"View\",\"ro\":\"Vizualizare\"}}},\"postEditAttachments\":{\"en\":\"Update attachments\",\"ro\":\"Editare ata\u0219amente\"},\"postEditIndex\":{\"en\":\"Update content\",\"ro\":\"Editare con\u021Binut\"},\"postFormat\":{\"en\":\"Post format\",\"ro\":\"Format postare\"},\"post_slug\":{\"en\":\"Permalink\",\"ro\":\"Permalink\"},\"posted_at\":{\"en\":\"Posted at\",\"ro\":\"Postat pe\"},\"posted_by\":{\"en\":\"by \\u003ca href=\\\"/profile/%[1]s\\\"\\u003e%[1]s\\u003c/a\\u003e\",\"ro\":\"de \\u003ca href=\\\"/profile/%[1]s\\\"\\u003e%[1]s\\u003c/a\\u003e\"},\"prepareDuration\":{\"en\":\"Prepare duration\",\"ro\":\"Durata preg\u0103tirii\"},\"privacyPolicy\":{\"en\":\"Privacy policy\",\"ro\":\"Politica de confiden\u021Bialitate\"},\"private\":{\"en\":\"Private\",\"ro\":\"Privat\"},\"privateAttachments\":{\"en\":\"Private attachments\",\"ro\":\"Ata\u0219amente private\"},\"problem\":{\"en\":\"Problem %d: %s\",\"list\":{\"en\":\"Problems\",\"ro\":\"Probleme\"},\"ro\":\"Problema %d: %s\"},\"problemID\":{\"en\":\"Problem ID\",\"ro\":\"ID Problem\u0103\"},\"problemInfo\":{\"en\":\"Problem info\",\"ro\":\"Detalii problem\u0103\"},\"problemListID\":{\"en\":\"Problem List ID\",\"ro\":\"ID List\u0103 Probleme\"},\"problemName\":{\"en\":\"Problem name\",\"ro\":\"Nume problem\u0103\"},\"problemSingle\":{\"en\":\"Problem\",\"ro\":\"Problema\"},\"problemStats\":{\"en\":\"Statistics\",\"ro\":\"Statistici\"},\"problem_checklist\":{\"en\":\"Problem checklist\",\"ro\":\"Verific\u0103ri problem\u0103\"},\"problem_contest_page_warning\":{\"en\":\"This was the problem page during the contest. \\u003ca id=\\\"pb_link_rewrite_a\\\" href=\\\"#\\\"\\u003eAccess the current page here\\u003c/a\\u003e.\",\"ro\":\"Aceasta a fost pagina problemei \u00EEn timpul concursului. \\u003ca id=\\\"pb_link_rewrite_a\\\" href=\\\"#\\\"\\u003eAcceseaz\u0103 pagina curent\u0103 aici\\u003c/a\\u003e.\"},\"problem_diagnostics\":{\"en\":\"Problem diagnostics\",\"ro\":\"Diagnostice problem\u0103\"},\"problem_list\":{\"none\":{\"en\":\"There are no problem lists\",\"ro\":\"Nu exist\u0103 nicio list\u0103 de probleme\"}},\"problem_lists\":{\"en\":\"Problem Lists\",\"ro\":\"Liste de Probleme\"},\"problem_tags\":{\"en\":\"Problem tags\",\"ro\":\"Etichete problem\u0103\"},\"problem_tags_explainer\":{\"en\":\"Add authors, techniques, etc.\",\"ro\":\"Adaug\u0103 autorii, tehnici de rezolvare, etc.\"},\"problems\":{\"en\":\"Problems\",\"ro\":\"Probleme\"},\"profile\":{\"en\":\"Profile:\",\"ro\":\"Profil:\",\"settings\":{\"en\":\"Profile settings\",\"ro\":\"Set\u0103ri profil\"},\"url\":{\"en\":\"Profile\",\"ro\":\"Profil\"}},\"profilePic\":{\"en\":\"Profile picture for\",\"ro\":\"Poz\u0103 profil pentru\"},\"progress_overview\":{\"en\":\"Progress overview\",\"ro\":\"Evaluare progres\"},\"proposer\":{\"en\":\"Proposer\",\"ro\":\"Propun\u0103tor\"},\"proposers\":{\"en\":\"Proposers\",\"ro\":\"Propun\u0103tori\"},\"publicJoin\":{\"en\":\"Open registration\",\"ro\":\"\u00CEnregistrare liber\u0103\"},\"public_leaderboard\":{\"en\":\"Public leaderboard\",\"ro\":\"Clasament public\"},\"published\":{\"en\":\"Published\",\"ro\":\"Publicat\u0103\"},\"published_at\":{\"en\":\"Published at\",\"ro\":\"Publicat\u0103 pe\"},\"purgeBio\":{\"en\":\"Remove bio\",\"ro\":\"\u0218tergere bio\"},\"pwdConfirmation\":{\"en\":\"Confirm password\",\"ro\":\"Confirmare parol\u0103\"},\"queryCount\":{\"en\":\"Number of DB queries\",\"ro\":\"Num\u0103rul de query-uri DB\"},\"questionCooldown\":{\"en\":\"Question cooldown\",\"ro\":\"Cooldown \u00EEntreb\u0103ri\"},\"question_response\":{\"en\":\"Response\",\"ro\":\"R\u0103spuns\"},\"question_text\":{\"en\":\"Question details\",\"ro\":\"Detalii \u00EEntrebare\"},\"questions\":{\"en\":\"Questions\",\"ro\":\"\u00CEntreb\u0103ri\"},\"quick_search\":{\"en\":\"Search problems\",\"ro\":\"C\u0103utare probleme\"},\"random_problem\":{\"en\":\"Get a random problem\",\"ro\":\"Problem\u0103 aleatorie\"},\"random_problem_announcement\":{\"en\":\"You can draw a random problem by [clicking here](/problems/random).\",\"ro\":\"Po\u021Bi s\u0103 vezi o problem\u0103 aleatorie [ap\u0103s\u00E2nd aici](/problems/random).\"},\"random_unsolved_problem\":{\"en\":\"Get a random, unsolved problem\",\"ro\":\"Problem\u0103 aleatorie nerezolvat\u0103\"},\"random_unsolved_problem_announcement\":{\"en\":\"You can draw a random, unsolved problem by [clicking here](/problems/random?unsolved=true).\",\"ro\":\"Po\u021Bi s\u0103 vezi o problem\u0103 aleatorie, nerezolvat\u0103 [ap\u0103s\u00E2nd aici](/problems/random?unsolved=true).\"},\"received_questions\":{\"en\":\"Received questions\",\"ro\":\"\u00CEntreb\u0103ri primite\"},\"recover\":{\"en\":\"Recover\",\"ro\":\"Recuperare\"},\"reevaling\":{\"en\":\"Awaiting re-evaluation\",\"ro\":\"A\u0219teapt\u0103 reevaluare\"},\"reevaluate\":{\"en\":\"Reevaluate submission\",\"ro\":\"Reevaluare submisie\"},\"register_btn\":{\"en\":\"Register\",\"ro\":\"\u00CEnregistrare\"},\"register_during_contest\":{\"en\":\"Registering during contest is allowed\",\"ro\":\"\u00CEnregistrarea utilizatorilor \u00EEn timpul concursului este permis\u0103\"},\"register_during_contest_warning\":{\"en\":\"this has no effect if open registration is disabled\",\"ro\":\"nu are niciun efect dac\u0103 \u00EEnregistrarea liber\u0103 este dezactivat\u0103\"},\"register_login_anchor\":{\"en\":\"Log in\",\"ro\":\"Logheaz\u0103-te\"},\"register_login_text\":{\"en\":\"to register\",\"ro\":\"pentru a te \u00EEnregistra\"},\"registered\":{\"en\":\"Registered\",\"ro\":\"\u00CEnregistrat\"},\"registration_closed\":{\"en\":\"Closed\",\"ro\":\"\u00CEnchis\"},\"registration_open\":{\"en\":\"Open\",\"ro\":\"Deschis\"},\"registration_status\":{\"en\":\"Registration status\",\"ro\":\"Status \u00EEnregistr\u0103ri\"},\"rejected\":{\"en\":\"Rejected\",\"ro\":\"Refuzat\"},\"relevant_tags\":{\"en\":\"Relevant tags\",\"ro\":\"Etichete relevante\"},\"reload\":{\"en\":\"Reload\",\"ro\":\"Re\u00EEnc\u0103rcare\"},\"remainingAttempts\":{\"en\":\"Remaining attempts\",\"ro\":\"Submisii r\u0103mase\"},\"remaining_time\":{\"en\":\"Remaining time\",\"ro\":\"Timp r\u0103mas\"},\"removeSub\":{\"en\":\"Remove submission\",\"ro\":\"\u0218tergere submisie\"},\"renderDuration\":{\"en\":\"Render duration\",\"ro\":\"Durata rand\u0103rii\"},\"requestStats\":{\"en\":\"Request statistics (debug info)\",\"ro\":\"Statistici pagin\u0103 (debug info)\"},\"resend\":{\"en\":\"Resend\",\"ro\":\"Retrimite\"},\"reset\":{\"en\":\"Reset\",\"ro\":\"Resetare\"},\"resetSubs\":{\"en\":\"Reset waiting submissions\",\"ro\":\"Resetare submisii \u00EEn a\u0219teptare\"},\"resetTitle\":{\"en\":\"Reset password for user %s\",\"ro\":\"Resetare parol\u0103 pentru utilizatorul %s\"},\"reset_pwd\":{\"en\":\"Reset password\",\"ro\":\"Resetare parol\u0103\"},\"respond_to_answer\":{\"en\":\"Create response\",\"ro\":\"Creare r\u0103spuns\"},\"response\":{\"en\":\"Response\",\"ro\":\"R\u0103spuns\"},\"results\":{\"en\":\"Latest results\",\"ro\":\"Ultimele rezultate\"},\"running_contests\":{\"en\":\"Running contests\",\"ro\":\"Concursuri \u00EEn desf\u0103\u0219urare\"},\"score\":{\"en\":\"Score\",\"ro\":\"Scor\"},\"scoreParams\":{\"en\":\"CMS score parameters (advanced)\",\"ro\":\"Parametri scor CMS (avansat)\"},\"scorePrecision\":{\"en\":\"Score precision (decimals after dot)\",\"ro\":\"Precizie scor (zecimale dup\u0103 virgul\u0103)\"},\"scoreScale\":{\"en\":\"Max score in leaderboard\",\"ro\":\"Scor maxim \u00EEn clasament\"},\"score_breakdown_title\":{\"en\":\"Score breakdown\",\"ro\":\"Analiza scorului\"},\"score_breakdown_unattempted\":{\"en\":\"It looks like the problem hasn't been attempted yet.\",\"ro\":\"Se pare c\u0103 \u00EEnc\u0103 n-a fost \u00EEncercat\u0103 problema.\"},\"scoring_strategy\":{\"en\":\"Scoring strategy\",\"ro\":\"Strategie punctare\"},\"search_pb\":{\"en\":\"Search\",\"ro\":\"C\u0103utare\"},\"search_tag\":{\"en\":\"Search tag\",\"ro\":\"C\u0103utare etichet\u0103\"},\"seconds\":{\"en\":\"seconds\",\"ro\":\"secunde\"},\"seeMany\":{\"en\":\"See %d more submissions\",\"ro\":\"Vezi \u00EEnc\u0103 %d de submisii\"},\"seeOne\":{\"en\":\"See one more submission\",\"ro\":\"Vezi \u00EEnc\u0103 o submisie\"},\"seeU20\":{\"en\":\"See %d more submissions\",\"ro\":\"Vezi \u00EEnc\u0103 %d submisii\"},\"selectChecklist\":{\"en\":\"Select a checklist to view\",\"ro\":\"Selecteaz\u0103 un progres de vizualizat\"},\"selectContest\":{\"en\":\"Select contest\",\"ro\":\"Selectare concurs\"},\"select_tags\":{\"en\":\"Select tags\",\"ro\":\"Selectare etichete\"},\"selectedType\":{\"en\":\"Selected statement type\",\"ro\":\"Tip enun\u021B selectat\"},\"selected_tags\":{\"en\":\"Selected tags\",\"ro\":\"Etichete selectate\"},\"send\":{\"en\":\"Send\",\"ro\":\"Trimite\"},\"serverTime\":{\"en\":\"Server time\",\"ro\":\"Ora serverului\"},\"session_devices\":{\"en\":\"Devices\",\"ro\":\"Dispozitive\"},\"session_mgmt_wip\":{\"en\":\"This is an experimental feature, it does not have all useful data and abilities.\",\"ro\":\"Aceasta este o func\u021Bionalitate experimental\u0103, \u00EEnc\u0103 nu dispune de toate datele \u0219i abilit\u0103\u021Bile utile.\"},\"settings\":{\"en\":\"Settings\",\"ro\":\"Set\u0103ri\"},\"settingsHeader\":{\"en\":\"Profile settings\",\"ro\":\"Set\u0103rile profilului\"},\"shared_by\":{\"en\":\"Shared by\",\"ro\":\"Distribuit de\"},\"show\":{\"en\":\"Show\",\"ro\":\"Afi\u0219are\"},\"showSourceCodeBtn\":{\"en\":\"Show source code\",\"ro\":\"Afi\u0219are cod surs\u0103\"},\"showSourceCodeExpl\":{\"en\":\"You haven't solved the problem. Please give it some more thought before looking at someone else's code.\",\"ro\":\"\u00CEnc\u0103 n-ai rezolvat problema. Ar fi indicat s\u0103 te mai g\u00E2nde\u0219ti la ea \u00EEnainte s\u0103 te ui\u021Bi la codul altei persoane.\"},\"showSourceCodeQ\":{\"en\":\"Show source code?\",\"ro\":\"Afi\u0219are cod surs\u0103?\"},\"show_tags\":{\"en\":\"Show tags\",\"ro\":\"Afi\u0219are etichete\"},\"sidebar_hidable\":{\"en\":\"Hide in sidebar\",\"ro\":\"Ascuns din sidebar\"},\"signupReminder\":{\"en\":\"Do not have an account? \\u003ca href=\\\"/signup\\\"\\u003eSign up\\u003c/a\\u003e!\",\"ro\":\"N-ai cont? \\u003ca href=\\\"/signup\\\"\\u003e\u00CEnregistreaz\u0103-te\\u003c/a\\u003e!\"},\"sim_name\":{\"en\":\"Simulation name\",\"ro\":\"Nume simulare\"},\"simulation\":{\"en\":\"Simulation\",\"ro\":\"Simulare\"},\"single_problem\":{\"en\":\"1 problem\",\"ro\":\"o problem\u0103\"},\"size\":{\"en\":\"Size\",\"ro\":\"Dimensiune\"},\"sizeLeaderboard\":{\"en\":\"Smallest submissions leaderboard\",\"ro\":\"Clasament submisii de dimensiune minim\u0103\"},\"solvedProblems\":{\"en\":\"Solved problems\",\"ro\":\"Probleme rezolvate\"},\"sorting\":{\"en\":\"Sorting criteria\",\"ro\":\"Criteriu de sortare\"},\"source\":{\"en\":\"Source\",\"ro\":\"Surs\u0103\"},\"sourceCode\":{\"en\":\"Source Code\",\"ro\":\"Codul Surs\u0103\"},\"sourceSize\":{\"en\":\"Maximum submission size\",\"ro\":\"Dimensiune maxim\u0103 submisii\"},\"special\":{\"en\":\"Special\",\"ro\":\"Eviden\u021Biat\u0103\"},\"spokenLanguage\":{\"en\":\"Language\",\"ro\":\"Limb\u0103\"},\"startTime\":{\"en\":\"Start time\",\"ro\":\"Or\u0103 de \u00EEnceput\"},\"start_contest\":{\"en\":\"Start contest\",\"ro\":\"\u00CEncepe concursul\"},\"start_now\":{\"en\":\"Start now\",\"ro\":\"\u00CEncepe acum\"},\"started\":{\"en\":\"Started\",\"ro\":\"\u00CEnceput\"},\"started_at\":{\"en\":\"Participation status\",\"ro\":\"Status participare\"},\"statement\":{\"en\":\"Problem Statement\",\"ro\":\"Enun\u021B Problem\u0103\"},\"statementFormat\":{\"en\":\"Statement format\",\"ro\":\"Format enun\u021B\"},\"statementLanguage\":{\"en\":\"Statement language\",\"ro\":\"Limb\u0103 enun\u021B\"},\"status\":{\"en\":\"Status\",\"ro\":\"Status\"},\"stmt\":{\"en\":\"Statement\",\"ro\":\"Enun\u021B\"},\"stmt_type\":{\"editorial\":{\"en\":\"Editorial\",\"ro\":\"Editorial\"},\"llm\":{\"en\":\"AI Translated\",\"ro\":\"Tradus prin AI\"},\"long\":{\"en\":\"Long format\",\"ro\":\"Format lung\"},\"short\":{\"en\":\"Short format\",\"ro\":\"Format scurt\"}},\"stringFlags\":{\"en\":\"String flags\",\"ro\":\"Flag-uri string\"},\"sub\":{\"en\":\"Submission\",\"ro\":\"Submisia\"},\"subDeleteConfirm\":{\"en\":\"Are you sure you want to delete this submission?\",\"ro\":\"E\u0219ti sigur c\u0103 vrei s\u0103 \u0219tergi aceast\u0103 submisie?\"},\"subStatus\":{\"en\":\"Status of submissions\",\"ro\":\"Stare submisii\"},\"subTask\":{\"en\":\"SubTask\",\"ro\":\"SubTask-ul\"},\"subTasks\":{\"en\":\"Subtasks\",\"ro\":\"Subtaskuri\"},\"sub_author\":{\"en\":\"Submission author\",\"ro\":\"Autor submisie\"},\"sub_id\":{\"en\":\"Submission ID\",\"ro\":\"ID Submisie\"},\"subcount\":{\"en\":\"# Submissions\",\"ro\":\"# Submisii\"},\"sublist_label\":{\"en\":\"Nested lists (IDs separated by a comma)\",\"ro\":\"Liste imbricate (ID-uri separate prin virgul\u0103)\"},\"sublist_noscript\":{\"en\":\"Browse list\",\"ro\":\"Exploreaz\u0103 lista\"},\"submission\":{\"list\":{\"en\":\"Submissions\",\"ro\":\"Submisii\"}},\"submissionCooldown\":{\"en\":\"Submission cooldown\",\"ro\":\"Cooldown submisii\"},\"submissions\":{\"en\":\"Submissions\",\"ro\":\"Submisii\"},\"submit\":{\"en\":\"Upload Code\",\"ro\":\"\u00CEnc\u0103rcare Cod\"},\"submitLogin\":{\"en\":\"\\u003ca href=\\\"/login\\\"\\u003eLog in\\u003c/a\\u003e or \\u003ca href=\\\"/signup\\\"\\u003esign up\\u003c/a\\u003e to be able to send submissions!\",\"ro\":\"\\u003ca href=\\\"/login\\\"\\u003eAutentific\u0103-te\\u003c/a\\u003e sau \\u003ca href=\\\"/signup\\\"\\u003e\u00EEnregistreaz\u0103-te\\u003c/a\\u003e pentru a putea trimite submisii!\"},\"submit_style\":{\"en\":\"Submit style\",\"ro\":\"Stil submisie\"},\"subtaskDeleteConfirm\":{\"en\":\"Are you sure you want to delete %d subtasks?\",\"ro\":\"E\u0219ti sigur c\u0103 vrei s\u0103 \u0219tergi %d subtaskuri?\"},\"suggest_resource\":{\"en\":\"Suggest resource\",\"ro\":\"Propune resurs\u0103\"},\"sum_subtasks_strat\":{\"en\":\"Sum of maximum subtasks\",\"ro\":\"Suma maximelor subtaskurilor\"},\"support_kn\":{\"en\":\"Support Kilonova\",\"ro\":\"Sus\u021Bine\u021Bi Kilonova\"},\"system\":{\"en\":\"System\",\"ro\":\"Sistem\"},\"tagDeleteConfirm\":{\"en\":\"Are you sure you want to delete this tag?\",\"ro\":\"E\u0219ti sigur c\u0103 vrei s\u0103 \u0219tergi aceast\u0103 etichet\u0103?\"},\"tag_complex_add_group\":{\"en\":\"Add tag group\",\"ro\":\"Ad\u0103ugare grup\u0103 etichete\"},\"tag_complex_explainer\":{\"en\":\"Must have, for each group, any of the following tags\",\"ro\":\"Trebuie s\u0103 con\u021Bin\u0103, pentru fiecare grup\u0103, oricare din etichetele\"},\"tag_complex_group\":{\"en\":\"Group %d\",\"ro\":\"Grupul %d\"},\"tag_complex_not\":{\"en\":\"NOT\",\"ro\":\"NU\"},\"tag_filter_complex_mode\":{\"en\":\"Advanced mode\",\"ro\":\"Modul avansat\"},\"tag_filter_simple_mode\":{\"en\":\"Simple mode\",\"ro\":\"Modul simplu\"},\"tag_header\":{\"en\":\"Tag\",\"ro\":\"Eticheta\"},\"tag_name\":{\"en\":\"Tag name...\",\"ro\":\"Nume etichet\u0103...\"},\"tag_names\":{\"author\":{\"en\":\"Author\",\"ro\":\"Autor\"},\"contest\":{\"en\":\"Contest\",\"ro\":\"Concurs\"},\"method\":{\"en\":\"Method\",\"ro\":\"Metod\u0103\"},\"other\":{\"en\":\"Other\",\"ro\":\"Diverse\"}},\"tag_pbs\":{\"en\":\"Problems matching tag\",\"ro\":\"Probleme cu aceast\u0103 etichet\u0103\"},\"tag_type\":{\"en\":\"Type\",\"ro\":\"Tip\"},\"tags\":{\"en\":\"Tags\",\"ro\":\"Etichete\"},\"termsOfService\":{\"en\":\"Terms of service\",\"ro\":\"Termeni \u0219i condi\u021Bii\"},\"test\":{\"en\":\"Test\",\"ro\":\"Testul\"},\"testArchive\":{\"en\":\"Upload .zip test/problem data archive\",\"ro\":\"\u00CEnc\u0103rcare arhiv\u0103 .zip cu teste/datele problemei\"},\"testAssociations\":{\"en\":\"Test Associations\",\"ro\":\"Asocieri teste\"},\"testDeleteConfirm\":{\"en\":\"Are you sure you want to delete %d tests?\",\"ro\":\"E\u0219ti sigur c\u0103 vrei s\u0103 \u0219tergi %d teste?\"},\"testID\":{\"en\":\"Test ID\",\"ro\":\"ID Test\"},\"testName\":{\"en\":\"Test name\",\"ro\":\"Nume test\"},\"test_verdict\":{\"compile_error\":{\"en\":\"Compile error\",\"ro\":\"Eroare de compilare\"},\"internal_error\":{\"en\":\"Internal error\",\"ro\":\"Eroare intern\u0103\"},\"memory_limit\":{\"en\":\"Memory limit exceeded\",\"ro\":\"Limita de memorie dep\u0103\u0219it\u0103\"},\"partial\":{\"en\":\"Partially correct\",\"ro\":\"Par\u021Bial corect\"},\"runtime_error\":{\"en\":\"Runtime error\",\"ro\":\"Eroare runtime\"},\"skipped\":{\"en\":\"Skipped\",\"ro\":\"Ignorat\"},\"success\":{\"en\":\"Correct\",\"ro\":\"Corect\"},\"test_x\":{\"en\":\"Test\",\"ro\":\"Testul\"},\"timeout\":{\"en\":\"Time limit exceeded\",\"ro\":\"Limita de timp dep\u0103\u0219it\u0103\"},\"walltimeout\":{\"en\":\"Time limit exceeded (wall clock)\",\"ro\":\"Limita de timp dep\u0103\u0219it\u0103 (wall clock)\"},\"wrong\":{\"en\":\"Wrong answer\",\"ro\":\"R\u0103spuns gre\u0219it\"}},\"testers\":{\"en\":\"Testers\",\"ro\":\"Testeri\"},\"tests\":{\"en\":\"Tests\",\"ro\":\"Teste\"},\"text\":{\"en\":\"Text\",\"ro\":\"Text\"},\"text_insert\":{\"en\":\"Insert text\",\"ro\":\"Inserare text\"},\"the_rest\":{\"en\":\"Other problems\",\"ro\":\"Alte probleme\"},\"time\":{\"en\":\"Time\",\"ro\":\"Timp\"},\"timeLeaderboard\":{\"en\":\"Fastest time leaderboard\",\"ro\":\"Clasament submisii de timp minim\"},\"timeLimit\":{\"en\":\"Time limit\",\"ro\":\"Limit\u0103 de timp\"},\"time_elapsed\":{\"en\":\"Time elapsed\",\"ro\":\"Timp \u00EEncheiat\"},\"title\":{\"blogPosts\":{\"en\":\"Posts\",\"ro\":\"Post\u0103ri\"},\"contest\":{\"create\":{\"en\":\"Create contest\",\"ro\":\"Creare concurs\"}},\"create_post\":{\"en\":\"Create post\",\"ro\":\"Creare postare\"},\"edit\":{\"access_control\":{\"en\":\"Access control | Problem #%d: %s\",\"ro\":\"Control acces | Problema #%d: %s\"},\"attachments\":{\"en\":\"Edit Attachments | Problem #%d: %s\",\"ro\":\"Editare Ata\u0219amente | Problema #%d: %s\"},\"description\":{\"en\":\"Edit Description | Problem #%d: %s\",\"ro\":\"Editare Descriere | Problema #%d: %s\"},\"index\":{\"en\":\"Edit Problem | Problem #%d: %s\",\"ro\":\"Editare Problem\u0103 | Problema #%d: %s\"},\"problem\":{\"en\":\"Editing problem\",\"ro\":\"Editare problem\u0103\"},\"subtask\":{\"en\":\"Update Subtasks | Problem #%d: %s\",\"ro\":\"Actualizare Subtasks | Problema #%d: %s\"},\"subtask_add\":{\"en\":\"Create Subtask | Problem #%d: %s\",\"ro\":\"Creare Subtask | Problema #%d: %s\"},\"subtask_edit\":{\"en\":\"Edit Subtask #%d | Problem #%d: %s\",\"ro\":\"Editare Subtask #%d | Problema #%d: %s\"},\"test_add\":{\"en\":\"Add Test | Problem #%d: %s\",\"ro\":\"Ad\u0103ugare Test | Problema #%d: %s\"},\"test_edit\":{\"en\":\"Edit Test #%d | Problem #%d: %s\",\"ro\":\"Editare Test #%d | Problema #%d: %s\"},\"tests\":{\"en\":\"Update Tests | Problem #%d: %s\",\"ro\":\"Actualizare Teste | Problema #%d: %s\"}},\"en\":\"Title\",\"invitation\":{\"en\":\"Invite for %s\",\"ro\":\"Invita\u021Bie pentru %s\"},\"list\":{\"en\":\"List #%d\",\"ro\":\"Lista #%d\"},\"past_submissions\":{\"en\":\"Past submissions | Problem #%d: %s\",\"ro\":\"Submisii anterioare | Problema #%d: %s\"},\"problem_archive\":{\"en\":\"Download problem archive | Problem #%d: %s\",\"ro\":\"Desc\u0103rcare arhiv\u0103 problem\u0103 | Problema #%d: %s\"},\"problem_statement\":{\"en\":\"Problem statement\",\"ro\":\"Enun\u021B problem\u0103\"},\"problem_submissions\":{\"en\":\"Submissions for\",\"ro\":\"Submisii pentru\"},\"problem_submit\":{\"en\":\"Upload code | Problem #%d: %s\",\"ro\":\"\u00CEnc\u0103rcare cod | Problema #%d: %s\"},\"progressChecklist\":{\"en\":\"Progress Checklist\",\"ro\":\"Checklist progres\"},\"ro\":\"Titlu\",\"tags\":{\"en\":\"Tags\",\"ro\":\"Etichete\"}},\"toggleNavbar\":{\"en\":\"Toggle navigation bar\",\"ro\":\"Afi\u0219are/ascundere bar\u0103 navigare\"},\"toggleTheme\":{\"en\":\"Toggle theme\",\"ro\":\"Schimbare tem\u0103\"},\"toggle_visibility\":{\"en\":\"Toggle visibility\",\"ro\":\"Schimbare vizibilitate\"},\"topbar\":{\"edit\":{\"en\":\"Edit Problem\",\"ro\":\"Editare Problem\u0103\"}},\"total\":{\"en\":\"Total\",\"ro\":\"Total\"},\"transaction_id\":{\"en\":\"Transaction ID\",\"ro\":\"ID Tranzac\u021Bie\"},\"translateStatement\":{\"en\":\"Translate Romanian statement (using AI)\",\"ro\":\"Traduce enun\u021Bul din rom\u00E2n\u0103 (prin AI)\"},\"translateStatementWarning\":{\"en\":\"Are you sure you want to do this? This feature is currently experimental. Created statements might have hallucinated differences produced by LLMs. Please make sure the translated text is correct before making public.\",\"ro\":\"E\u0219ti sigur c\u0103 vrei s\u0103 faci asta? Acest feature este, momentan, experimental. Enun\u021Burile create pot avea diferen\u021Be halucinate de LLM-uri. Te rog s\u0103 asiguri faptul c\u0103 textul tradus este corect \u00EEnainte s\u0103 devin\u0103 public.\"},\"u20Results\":{\"en\":\"results\",\"ro\":\"rezultate\"},\"unanswered_questions\":{\"en\":\"Asked questions\",\"ro\":\"\u00CEntreb\u0103ri puse\"},\"unknownUser\":{\"en\":\"Unknown user\",\"ro\":\"Utilizator necunoscut\"},\"unlimitedAttempts\":{\"en\":\"Unlimited\",\"ro\":\"Nelimitat\"},\"unpublished\":{\"en\":\"Unpublished\",\"ro\":\"Nepublicat\u0103\"},\"unverifiedEmail\":{\"en\":\"It looks like you haven't verified your email yet. Click \\u003ca class=\\\"underline text-black dark:text-white\\\" href=\\\"/verify/resend\\\"\\u003ehere\\u003c/a\\u003e if you need to have your verification resent.\",\"ro\":\"Se pare c\u0103 \u00EEnc\u0103 nu \u021Bi-ai verificat emailul. Apas\u0103 \\u003ca class=\\\"underline text-black dark:text-white\\\" href=\\\"/verify/resend\\\"\\u003eaici\\u003c/a\\u003e dac\u0103 trebuie s\u0103 reprime\u0219ti verificarea.\"},\"updateAttachments\":{\"en\":\"Update attachment info\",\"ro\":\"Actualizare informa\u021Bii ata\u0219amente\"},\"updateBio\":{\"en\":\"Update Bio\",\"ro\":\"Actualizare Bio\"},\"updateEmail\":{\"en\":\"Update email\",\"ro\":\"Actualizare email\"},\"updateFlags\":{\"en\":\"Update flags\",\"ro\":\"Actualizare flag-uri\"},\"updateLang\":{\"en\":\"Update default display language\",\"ro\":\"Actualizare limb\u0103 implicit\u0103 pentru afi\u0219aj\"},\"updateProblem\":{\"en\":\"Update problem info\",\"ro\":\"Actualizare date problem\u0103\"},\"updateProblemTestsHidden\":{\"en\":\"tests: hidden\",\"ro\":\"teste: ascunse\"},\"updateProblemTestsVisible\":{\"en\":\"tests: visible\",\"ro\":\"teste: vizibile\"},\"updateProblems1\":{\"en\":\"Update \",\"ro\":\"Actualizare \"},\"updateProblems2\":{\"en\":\", set \",\"ro\":\", seteaz\u0103 \"},\"updateProblemsHidden\":{\"en\":\"visibility: hidden\",\"ro\":\"vizibilitate: ascunse\"},\"updateProblemsRecursive\":{\"en\":\"all problems, recursively\",\"ro\":\"toate problemele, recursiv\"},\"updateProblemsShallow\":{\"en\":\"all list problems\",\"ro\":\"toate problemele listei\"},\"updateProblemsVisible\":{\"en\":\"visibility: visible\",\"ro\":\"vizibilitate: vizibile\"},\"updatePwd\":{\"en\":\"Update password\",\"ro\":\"Actualizare parol\u0103\"},\"updateSubTasks\":{\"en\":\"Update Subtask scores\",\"ro\":\"Actualizare scoruri Subtasks\"},\"updateTest\":{\"en\":\"Update test %d\",\"ro\":\"Actualizare test %d\"},\"updateTestFiles\":{\"en\":\"Upload replacement files for test\",\"ro\":\"\u00CEnc\u0103rcare fi\u0219iere de \u00EEnlocuire pentru test\"},\"updateTestScores\":{\"en\":\"Update test scores\",\"ro\":\"Actualizeaz\u0103 scorurile testelor\"},\"update_tag\":{\"en\":\"Update tag information\",\"ro\":\"Actualizare informa\u021Bii etichet\u0103\"},\"update_tags\":{\"en\":\"Update tags\",\"ro\":\"Actualizare etichete\"},\"updated_at\":{\"en\":\"Updated at\",\"ro\":\"Actualizat pe\"},\"uploadContestSub\":{\"en\":\"Send contest submission\",\"ro\":\"Trimitere submisie de concurs\"},\"uploadDate\":{\"en\":\"Upload date\",\"ro\":\"Data \u00EEnc\u0103rc\u0103rii\"},\"uploadSub\":{\"en\":\"Upload submission\",\"ro\":\"\u00CEnc\u0103rcare submisie\"},\"upload_file\":{\"en\":\"Upload file\",\"ro\":\"\u00CEnc\u0103rcare fi\u0219ier\"},\"upload_method\":{\"en\":\"Upload method\",\"ro\":\"Metod\u0103 \u00EEnc\u0103rcare\"},\"upload_processing\":{\"en\":\"Upload complete, processing request\",\"ro\":\"\u00CEnc\u0103rcare finalizat\u0103, se proceseaz\u0103 request-ul\"},\"uploaded\":{\"en\":\"Submission uploaded\",\"ro\":\"Submisie \u00EEnc\u0103rcat\u0103\"},\"uploader\":{\"en\":\"Uploader\",\"ro\":\"Uploader\"},\"uploading\":{\"en\":\"Uploading...\",\"ro\":\"Se \u00EEncarc\u0103...\"},\"upsolveSub\":{\"en\":\"Upload unofficial submission\",\"ro\":\"\u00CEnc\u0103rcare submisie neoficial\u0103\"},\"usaco_expired_helper\":{\"en\":\"Time expired. Problems will be available again after the contest ends.\",\"ro\":\"Timp expirat. Problemele vor fi disponibile din nou dup\u0103 ce se \u00EEncheie concursul.\"},\"usaco_helper_text\":{\"en\":\"This is an USACO-style contest. Problems will be available once you press the start button in the sidebar. You will be given %s to finish the problems.\",\"ro\":\"Acesta este un concurs stil USACO. Problemele vor fi disponibile odat\u0103 ce ape\u0219i butonul de start. Vei avea %s s\u0103 termini problemele.\"},\"use_in_search\":{\"en\":\"Use in search\",\"ro\":\"Folose\u0219te \u00EEn c\u0103utare\"},\"usefulInfo\":{\"en\":\"Useful Links\",\"ro\":\"Link-uri utile\"},\"userID\":{\"en\":\"User ID\",\"ro\":\"ID User\"},\"user_gen\":{\"created_accounts\":{\"en\":\"Created accounts\",\"ro\":\"Conturile create\"},\"created_accounts_info\":{\"en\":\"Passwords will be lost on page reload, they are not saved anywhere.\",\"ro\":\"Parolele vor fi pierdute c\u00E2nd se re\u00EEncarc\u0103 pagina, nu sunt salvate niciunde.\"},\"display_name\":{\"en\":\"Display name\",\"ro\":\"Nume de afi\u0219aj\"},\"optional_fields\":{\"en\":\"All fields except username are optional.\",\"ro\":\"Toate c\u00E2mpurile, cu excep\u021Bia celui de username, sunt op\u021Bionale.\"},\"password_by_mail\":{\"en\":\"Send password through email\",\"ro\":\"Trimite parol\u0103 prin email\"},\"password_mail_address\":{\"en\":\"Override email address for password\",\"ro\":\"Trimite parola la alt\u0103 adres\u0103\"},\"password_mail_subject\":{\"en\":\"Email Subject\",\"ro\":\"Subiect Email\"},\"title\":{\"en\":\"Generate user\",\"ro\":\"Generare utilizator\"}},\"username\":{\"en\":\"Username\",\"ro\":\"Username\"},\"usernameChangeDetails\":{\"en\":\"An admin has flagged your account for a required username change. It may be because it contains obscene remarks, could be considered spam or uses characters that aren't allowed anymore.\",\"ro\":\"Un administrator a marcat contul t\u0103u pentru o schimbare necesar\u0103 a numelui. E posibil ca numele prezent s\u0103 con\u021Bin\u0103 cuvinte obscene, poate fi considerat spam sau folose\u0219te caractere care nu mai sunt permise.\"},\"usernameChangeForced\":{\"en\":\"Username change required\",\"ro\":\"Este necesar\u0103 schimbarea username-ului\"},\"usernameChangeHistory\":{\"en\":\"Username history\",\"ro\":\"Istoric username\"},\"usernameChangeUniqueRemark\":{\"en\":\"Please choose a new name that wasn't used before.\",\"ro\":\"Te rug\u0103m s\u0103 introduci un nume nou care nu s-a mai folosit p\u00E2n\u0103 acum.\"},\"usernameChangeWarning\":{\"en\":\"Please note that if the new name is not appropriate, the admins may lock your account.\",\"ro\":\"Te rug\u0103m s\u0103 iei \u00EEn vedere faptul c\u0103 dac\u0103 numele nou nu este adecvat, administratorii ar putea bloca contul.\"},\"username_email\":{\"en\":\"Username/Email\",\"ro\":\"Username/Email\"},\"users\":{\"en\":\"Users\",\"ro\":\"Utilizatori\"},\"value\":{\"en\":\"Value\",\"ro\":\"Valoare\"},\"variantChangeConfirm\":{\"en\":\"You have unsaved changes. Are you sure you want to discard changes?\",\"ro\":\"Ai modific\u0103ri nesalvate. Sigur vrei s\u0103 schimbi fi\u0219ierul pe care \u00EEl editezi? Con\u021Binutul actual nu va fi salvat.\"},\"verdict\":{\"en\":\"Verdict\",\"ro\":\"Verdict\"},\"view\":{\"en\":\"View\",\"ro\":\"Vizualizare\"},\"viewAllLists\":{\"en\":\"View all lists\",\"ro\":\"Vizualizare toate listele\"},\"view_details\":{\"en\":\"View details\",\"ro\":\"Vezi detalii\"},\"view_more\":{\"en\":\"View more\",\"ro\":\"Vezi mai multe\"},\"viewers\":{\"en\":\"Viewers\",\"ro\":\"Vizualizatori\"},\"viewingFromList\":{\"en\":\"Viewing problems from\",\"ro\":\"Se vizualizeaz\u0103 probleme din\"},\"virtual\":{\"en\":\"Virtual\",\"ro\":\"Virtual\"},\"visibility\":{\"en\":\"Visibility\",\"ro\":\"Vizibilitate\"},\"visibility_admin\":{\"en\":\"Only admins can change problem visibility\",\"ro\":\"Numai adminii pot s\u0103 schimbe vizibilitatea unei probleme\"},\"visible\":{\"en\":\"Visible\",\"ro\":\"Vizibil\"},\"visibleTests\":{\"en\":\"Visible tests (anyone can download problem archive)\",\"ro\":\"Teste vizibile (oricine poate desc\u0103rca arhiva problemei)\"},\"waiting\":{\"en\":\"Waiting...\",\"ro\":\"\u00CEn a\u0219teptare...\"},\"warmingUp\":{\"en\":\"Warming up...\",\"ro\":\"Se genereaz\u0103...\"},\"warning\":{\"emptySubTask\":{\"en\":\"WARNING: Empty Subtask, will always show 0 points\",\"ro\":\"WARNING: Subtask gol, va afi\u0219a mereu 0 puncte\"}},\"working\":{\"en\":\"Working\",\"ro\":\"\u00CEn lucru\"},\"yes\":{\"en\":\"Yes\",\"ro\":\"Da\"}}", "import { createToast, dismissToast } from \"../toast\";\nimport getText from \"../translation\";\nimport { Response, defaultClient } from \"./client\";\n\nexport async function multipartProgressCall(call: string, formdata: FormData): Promise> {\n\tif (call.startsWith(\"/\")) {\n\t\tcall = call.substring(1);\n\t}\n\ttry {\n\t\tconst id = Math.random();\n\t\tconst toast = createToast({\n\t\t\tstatus: \"progress\",\n\t\t\ttitle: getText(\"uploading\"),\n\t\t\tdescription: ``,\n\t\t});\n\t\tconst xhr = new XMLHttpRequest();\n\t\tconst resp = await new Promise>((resolve) => {\n\t\t\txhr.open(\"POST\", `/api/${call}`, true);\n\t\t\txhr.responseType = \"json\";\n\t\t\txhr.upload.addEventListener(\"progress\", (e) => {\n\t\t\t\tdocument.dispatchEvent(\n\t\t\t\t\tnew CustomEvent(\"kn-upload-update\", {\n\t\t\t\t\t\tdetail: {\n\t\t\t\t\t\t\tid: id,\n\t\t\t\t\t\t\tcntLoaded: e.loaded,\n\t\t\t\t\t\t\tcntTotal: e.total,\n\t\t\t\t\t\t\tcomputable: e.lengthComputable,\n\t\t\t\t\t\t\tprocessing: false,\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t});\n\t\t\txhr.upload.addEventListener(\"load\", (e) => {\n\t\t\t\tdocument.dispatchEvent(\n\t\t\t\t\tnew CustomEvent(\"kn-upload-update\", {\n\t\t\t\t\t\tdetail: {\n\t\t\t\t\t\t\tid: id,\n\t\t\t\t\t\t\tcntLoaded: e.loaded,\n\t\t\t\t\t\t\tcntTotal: e.total,\n\t\t\t\t\t\t\tcomputable: e.lengthComputable,\n\t\t\t\t\t\t\tprocessing: true,\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t});\n\t\t\txhr.upload.addEventListener(\"error\", (e) => {\n\t\t\t\tconsole.error(e, xhr.statusText);\n\t\t\t\tresolve({\n\t\t\t\t\tstatus: \"error\",\n\t\t\t\t\tdata: \"Upload error\",\n\t\t\t\t\tstatusCode: xhr.status,\n\t\t\t\t});\n\t\t\t});\n\t\t\txhr.addEventListener(\"load\", () => {\n\t\t\t\tresolve(xhr.response);\n\t\t\t});\n\t\t\txhr.addEventListener(\"error\", (e) => {\n\t\t\t\tconsole.error(e);\n\t\t\t\tresolve({\n\t\t\t\t\tstatus: \"error\",\n\t\t\t\t\tdata: xhr.statusText,\n\t\t\t\t\tstatusCode: xhr.status,\n\t\t\t\t});\n\t\t\t});\n\t\t\txhr.setRequestHeader(\"Accept\", \"application/json\");\n\t\t\txhr.setRequestHeader(\"Authorization\", defaultClient.session);\n\t\t\txhr.send(formdata);\n\t\t});\n\t\tdocument.dispatchEvent(\n\t\t\tnew CustomEvent(\"kn-upload-update\", {\n\t\t\t\tdetail: {\n\t\t\t\t\tid: id,\n\t\t\t\t\tcntLoaded: 1,\n\t\t\t\t\tcntTotal: 1,\n\t\t\t\t\tcomputable: true,\n\t\t\t\t\tprocessing: false,\n\t\t\t\t},\n\t\t\t})\n\t\t);\n\t\tdismissToast(toast);\n\t\treturn resp;\n\t} catch (e: any) {\n\t\treturn { status: \"error\", data: e.toString(), statusCode: 500 };\n\t}\n}\n", "/** Normal hydration that attaches to a DOM tree but does not diff it. */\nexport const MODE_HYDRATE = 1 << 5;\n/** Signifies this VNode suspended on the previous render */\nexport const MODE_SUSPENDED = 1 << 7;\n/** Indicates that this node needs to be inserted while patching children */\nexport const INSERT_VNODE = 1 << 2;\n/** Indicates a VNode has been matched with another VNode in the diff */\nexport const MATCHED = 1 << 1;\n\n/** Reset all mode flags */\nexport const RESET_MODE = ~(MODE_HYDRATE | MODE_SUSPENDED);\n\nexport const SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\nexport const XHTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';\nexport const MATH_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';\n\nexport const UNDEFINED = undefined;\nexport const EMPTY_OBJ = /** @type {any} */ ({});\nexport const EMPTY_ARR = [];\nexport const IS_NON_DIMENSIONAL =\n\t/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;\n", "import { EMPTY_ARR } from './constants';\n\nexport const isArray = Array.isArray;\n\n/**\n * Assign properties from `props` to `obj`\n * @template O, P The obj and props types\n * @param {O} obj The object to copy properties to\n * @param {P} props The object to copy properties from\n * @returns {O & P}\n */\nexport function assign(obj, props) {\n\t// @ts-expect-error We change the type of `obj` to be `O & P`\n\tfor (let i in props) obj[i] = props[i];\n\treturn /** @type {O & P} */ (obj);\n}\n\n/**\n * Remove a child node from its parent if attached. This is a workaround for\n * IE11 which doesn't support `Element.prototype.remove()`. Using this function\n * is smaller than including a dedicated polyfill.\n * @param {import('./index').ContainerNode} node The node to remove\n */\nexport function removeNode(node) {\n\tif (node && node.parentNode) node.parentNode.removeChild(node);\n}\n\nexport const slice = EMPTY_ARR.slice;\n", "import { _catchError } from './diff/catch-error';\n\n/**\n * The `option` object can potentially contain callback functions\n * that are called during various stages of our renderer. This is the\n * foundation on which all our addons like `preact/debug`, `preact/compat`,\n * and `preact/hooks` are based on. See the `Options` type in `internal.d.ts`\n * for a full list of available option hooks (most editors/IDEs allow you to\n * ctrl+click or cmd+click on mac the type definition below).\n * @type {import('./internal').Options}\n */\nconst options = {\n\t_catchError\n};\n\nexport default options;\n", "import { slice } from './util';\nimport options from './options';\nimport { UNDEFINED } from './constants';\n\nlet vnodeId = 0;\n\n/**\n * Create an virtual node (used for JSX)\n * @param {import('./internal').VNode[\"type\"]} type The node name or Component constructor for this\n * virtual node\n * @param {object | null | undefined} [props] The properties of the virtual node\n * @param {Array} [children] The children of the\n * virtual node\n * @returns {import('./internal').VNode}\n */\nexport function createElement(type, props, children) {\n\tlet normalizedProps = {},\n\t\tkey,\n\t\tref,\n\t\ti;\n\tfor (i in props) {\n\t\tif (i == 'key') key = props[i];\n\t\telse if (i == 'ref') ref = props[i];\n\t\telse normalizedProps[i] = props[i];\n\t}\n\n\tif (arguments.length > 2) {\n\t\tnormalizedProps.children =\n\t\t\targuments.length > 3 ? slice.call(arguments, 2) : children;\n\t}\n\n\t// If a Component VNode, check for and apply defaultProps\n\t// Note: type may be undefined in development, must never error here.\n\tif (typeof type == 'function' && type.defaultProps != null) {\n\t\tfor (i in type.defaultProps) {\n\t\t\tif (normalizedProps[i] === UNDEFINED) {\n\t\t\t\tnormalizedProps[i] = type.defaultProps[i];\n\t\t\t}\n\t\t}\n\t}\n\n\treturn createVNode(type, normalizedProps, key, ref, null);\n}\n\n/**\n * Create a VNode (used internally by Preact)\n * @param {import('./internal').VNode[\"type\"]} type The node name or Component\n * Constructor for this virtual node\n * @param {object | string | number | null} props The properties of this virtual node.\n * If this virtual node represents a text node, this is the text of the node (string or number).\n * @param {string | number | null} key The key for this virtual node, used when\n * diffing it against its children\n * @param {import('./internal').VNode[\"ref\"]} ref The ref property that will\n * receive a reference to its created child\n * @returns {import('./internal').VNode}\n */\nexport function createVNode(type, props, key, ref, original) {\n\t// V8 seems to be better at detecting type shapes if the object is allocated from the same call site\n\t// Do not inline into createElement and coerceToVNode!\n\t/** @type {import('./internal').VNode} */\n\tconst vnode = {\n\t\ttype,\n\t\tprops,\n\t\tkey,\n\t\tref,\n\t\t_children: null,\n\t\t_parent: null,\n\t\t_depth: 0,\n\t\t_dom: null,\n\t\t_component: null,\n\t\tconstructor: UNDEFINED,\n\t\t_original: original == null ? ++vnodeId : original,\n\t\t_index: -1,\n\t\t_flags: 0\n\t};\n\n\t// Only invoke the vnode hook if this was *not* a direct copy:\n\tif (original == null && options.vnode != null) options.vnode(vnode);\n\n\treturn vnode;\n}\n\nexport function createRef() {\n\treturn { current: null };\n}\n\nexport function Fragment(props) {\n\treturn props.children;\n}\n\n/**\n * Check if a the argument is a valid Preact VNode.\n * @param {*} vnode\n * @returns {vnode is VNode}\n */\nexport const isValidElement = vnode =>\n\tvnode != null && vnode.constructor == UNDEFINED;\n", "import { assign } from './util';\nimport { diff, commitRoot } from './diff/index';\nimport options from './options';\nimport { Fragment } from './create-element';\nimport { MODE_HYDRATE } from './constants';\n\n/**\n * Base Component class. Provides `setState()` and `forceUpdate()`, which\n * trigger rendering\n * @param {object} props The initial component props\n * @param {object} context The initial context from parent components'\n * getChildContext\n */\nexport function BaseComponent(props, context) {\n\tthis.props = props;\n\tthis.context = context;\n}\n\n/**\n * Update component state and schedule a re-render.\n * @this {import('./internal').Component}\n * @param {object | ((s: object, p: object) => object)} update A hash of state\n * properties to update with new values or a function that given the current\n * state and props returns a new partial state\n * @param {() => void} [callback] A function to be called once component state is\n * updated\n */\nBaseComponent.prototype.setState = function (update, callback) {\n\t// only clone state when copying to nextState the first time.\n\tlet s;\n\tif (this._nextState != null && this._nextState !== this.state) {\n\t\ts = this._nextState;\n\t} else {\n\t\ts = this._nextState = assign({}, this.state);\n\t}\n\n\tif (typeof update == 'function') {\n\t\t// Some libraries like `immer` mark the current state as readonly,\n\t\t// preventing us from mutating it, so we need to clone it. See #2716\n\t\tupdate = update(assign({}, s), this.props);\n\t}\n\n\tif (update) {\n\t\tassign(s, update);\n\t}\n\n\t// Skip update if updater function returned null\n\tif (update == null) return;\n\n\tif (this._vnode) {\n\t\tif (callback) {\n\t\t\tthis._stateCallbacks.push(callback);\n\t\t}\n\t\tenqueueRender(this);\n\t}\n};\n\n/**\n * Immediately perform a synchronous re-render of the component\n * @this {import('./internal').Component}\n * @param {() => void} [callback] A function to be called after component is\n * re-rendered\n */\nBaseComponent.prototype.forceUpdate = function (callback) {\n\tif (this._vnode) {\n\t\t// Set render mode so that we can differentiate where the render request\n\t\t// is coming from. We need this because forceUpdate should never call\n\t\t// shouldComponentUpdate\n\t\tthis._force = true;\n\t\tif (callback) this._renderCallbacks.push(callback);\n\t\tenqueueRender(this);\n\t}\n};\n\n/**\n * Accepts `props` and `state`, and returns a new Virtual DOM tree to build.\n * Virtual DOM is generally constructed via [JSX](http://jasonformat.com/wtf-is-jsx).\n * @param {object} props Props (eg: JSX attributes) received from parent\n * element/component\n * @param {object} state The component's current state\n * @param {object} context Context object, as returned by the nearest\n * ancestor's `getChildContext()`\n * @returns {ComponentChildren | void}\n */\nBaseComponent.prototype.render = Fragment;\n\n/**\n * @param {import('./internal').VNode} vnode\n * @param {number | null} [childIndex]\n */\nexport function getDomSibling(vnode, childIndex) {\n\tif (childIndex == null) {\n\t\t// Use childIndex==null as a signal to resume the search from the vnode's sibling\n\t\treturn vnode._parent\n\t\t\t? getDomSibling(vnode._parent, vnode._index + 1)\n\t\t\t: null;\n\t}\n\n\tlet sibling;\n\tfor (; childIndex < vnode._children.length; childIndex++) {\n\t\tsibling = vnode._children[childIndex];\n\n\t\tif (sibling != null && sibling._dom != null) {\n\t\t\t// Since updateParentDomPointers keeps _dom pointer correct,\n\t\t\t// we can rely on _dom to tell us if this subtree contains a\n\t\t\t// rendered DOM node, and what the first rendered DOM node is\n\t\t\treturn sibling._dom;\n\t\t}\n\t}\n\n\t// If we get here, we have not found a DOM node in this vnode's children.\n\t// We must resume from this vnode's sibling (in it's parent _children array)\n\t// Only climb up and search the parent if we aren't searching through a DOM\n\t// VNode (meaning we reached the DOM parent of the original vnode that began\n\t// the search)\n\treturn typeof vnode.type == 'function' ? getDomSibling(vnode) : null;\n}\n\n/**\n * Trigger in-place re-rendering of a component.\n * @param {import('./internal').Component} component The component to rerender\n */\nfunction renderComponent(component) {\n\tlet oldVNode = component._vnode,\n\t\toldDom = oldVNode._dom,\n\t\tcommitQueue = [],\n\t\trefQueue = [];\n\n\tif (component._parentDom) {\n\t\tconst newVNode = assign({}, oldVNode);\n\t\tnewVNode._original = oldVNode._original + 1;\n\t\tif (options.vnode) options.vnode(newVNode);\n\n\t\tdiff(\n\t\t\tcomponent._parentDom,\n\t\t\tnewVNode,\n\t\t\toldVNode,\n\t\t\tcomponent._globalContext,\n\t\t\tcomponent._parentDom.namespaceURI,\n\t\t\toldVNode._flags & MODE_HYDRATE ? [oldDom] : null,\n\t\t\tcommitQueue,\n\t\t\toldDom == null ? getDomSibling(oldVNode) : oldDom,\n\t\t\t!!(oldVNode._flags & MODE_HYDRATE),\n\t\t\trefQueue\n\t\t);\n\n\t\tnewVNode._original = oldVNode._original;\n\t\tnewVNode._parent._children[newVNode._index] = newVNode;\n\t\tcommitRoot(commitQueue, newVNode, refQueue);\n\n\t\tif (newVNode._dom != oldDom) {\n\t\t\tupdateParentDomPointers(newVNode);\n\t\t}\n\t}\n}\n\n/**\n * @param {import('./internal').VNode} vnode\n */\nfunction updateParentDomPointers(vnode) {\n\tif ((vnode = vnode._parent) != null && vnode._component != null) {\n\t\tvnode._dom = vnode._component.base = null;\n\t\tfor (let i = 0; i < vnode._children.length; i++) {\n\t\t\tlet child = vnode._children[i];\n\t\t\tif (child != null && child._dom != null) {\n\t\t\t\tvnode._dom = vnode._component.base = child._dom;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn updateParentDomPointers(vnode);\n\t}\n}\n\n/**\n * The render queue\n * @type {Array}\n */\nlet rerenderQueue = [];\n\n/*\n * The value of `Component.debounce` must asynchronously invoke the passed in callback. It is\n * important that contributors to Preact can consistently reason about what calls to `setState`, etc.\n * do, and when their effects will be applied. See the links below for some further reading on designing\n * asynchronous APIs.\n * * [Designing APIs for Asynchrony](https://blog.izs.me/2013/08/designing-apis-for-asynchrony)\n * * [Callbacks synchronous and asynchronous](https://blog.ometer.com/2011/07/24/callbacks-synchronous-and-asynchronous/)\n */\n\nlet prevDebounce;\n\nconst defer =\n\ttypeof Promise == 'function'\n\t\t? Promise.prototype.then.bind(Promise.resolve())\n\t\t: setTimeout;\n\n/**\n * Enqueue a rerender of a component\n * @param {import('./internal').Component} c The component to rerender\n */\nexport function enqueueRender(c) {\n\tif (\n\t\t(!c._dirty &&\n\t\t\t(c._dirty = true) &&\n\t\t\trerenderQueue.push(c) &&\n\t\t\t!process._rerenderCount++) ||\n\t\tprevDebounce !== options.debounceRendering\n\t) {\n\t\tprevDebounce = options.debounceRendering;\n\t\t(prevDebounce || defer)(process);\n\t}\n}\n\n/**\n * @param {import('./internal').Component} a\n * @param {import('./internal').Component} b\n */\nconst depthSort = (a, b) => a._vnode._depth - b._vnode._depth;\n\n/** Flush the render queue by rerendering all queued components */\nfunction process() {\n\tlet c;\n\trerenderQueue.sort(depthSort);\n\t// Don't update `renderCount` yet. Keep its value non-zero to prevent unnecessary\n\t// process() calls from getting scheduled while `queue` is still being consumed.\n\twhile ((c = rerenderQueue.shift())) {\n\t\tif (c._dirty) {\n\t\t\tlet renderQueueLength = rerenderQueue.length;\n\t\t\trenderComponent(c);\n\t\t\tif (rerenderQueue.length > renderQueueLength) {\n\t\t\t\t// When i.e. rerendering a provider additional new items can be injected, we want to\n\t\t\t\t// keep the order from top to bottom with those new items so we can handle them in a\n\t\t\t\t// single pass\n\t\t\t\trerenderQueue.sort(depthSort);\n\t\t\t}\n\t\t}\n\t}\n\tprocess._rerenderCount = 0;\n}\n\nprocess._rerenderCount = 0;\n", "import { IS_NON_DIMENSIONAL, SVG_NAMESPACE } from '../constants';\nimport options from '../options';\n\nfunction setStyle(style, key, value) {\n\tif (key[0] == '-') {\n\t\tstyle.setProperty(key, value == null ? '' : value);\n\t} else if (value == null) {\n\t\tstyle[key] = '';\n\t} else if (typeof value != 'number' || IS_NON_DIMENSIONAL.test(key)) {\n\t\tstyle[key] = value;\n\t} else {\n\t\tstyle[key] = value + 'px';\n\t}\n}\n\nconst CAPTURE_REGEX = /(PointerCapture)$|Capture$/i;\n\n// A logical clock to solve issues like https://github.com/preactjs/preact/issues/3927.\n// When the DOM performs an event it leaves micro-ticks in between bubbling up which means that\n// an event can trigger on a newly reated DOM-node while the event bubbles up.\n//\n// Originally inspired by Vue\n// (https://github.com/vuejs/core/blob/caeb8a68811a1b0f79/packages/runtime-dom/src/modules/events.ts#L90-L101),\n// but modified to use a logical clock instead of Date.now() in case event handlers get attached\n// and events get dispatched during the same millisecond.\n//\n// The clock is incremented after each new event dispatch. This allows 1 000 000 new events\n// per second for over 280 years before the value reaches Number.MAX_SAFE_INTEGER (2**53 - 1).\nlet eventClock = 0;\n\n/**\n * Set a property value on a DOM node\n * @param {import('../internal').PreactElement} dom The DOM node to modify\n * @param {string} name The name of the property to set\n * @param {*} value The value to set the property to\n * @param {*} oldValue The old value the property had\n * @param {string} namespace Whether or not this DOM node is an SVG node or not\n */\nexport function setProperty(dom, name, value, oldValue, namespace) {\n\tlet useCapture;\n\n\to: if (name == 'style') {\n\t\tif (typeof value == 'string') {\n\t\t\tdom.style.cssText = value;\n\t\t} else {\n\t\t\tif (typeof oldValue == 'string') {\n\t\t\t\tdom.style.cssText = oldValue = '';\n\t\t\t}\n\n\t\t\tif (oldValue) {\n\t\t\t\tfor (name in oldValue) {\n\t\t\t\t\tif (!(value && name in value)) {\n\t\t\t\t\t\tsetStyle(dom.style, name, '');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (value) {\n\t\t\t\tfor (name in value) {\n\t\t\t\t\tif (!oldValue || value[name] !== oldValue[name]) {\n\t\t\t\t\t\tsetStyle(dom.style, name, value[name]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t// Benchmark for comparison: https://esbench.com/bench/574c954bdb965b9a00965ac6\n\telse if (name[0] == 'o' && name[1] == 'n') {\n\t\tuseCapture = name != (name = name.replace(CAPTURE_REGEX, '$1'));\n\n\t\t// Infer correct casing for DOM built-in events:\n\t\tif (\n\t\t\tname.toLowerCase() in dom ||\n\t\t\tname == 'onFocusOut' ||\n\t\t\tname == 'onFocusIn'\n\t\t)\n\t\t\tname = name.toLowerCase().slice(2);\n\t\telse name = name.slice(2);\n\n\t\tif (!dom._listeners) dom._listeners = {};\n\t\tdom._listeners[name + useCapture] = value;\n\n\t\tif (value) {\n\t\t\tif (!oldValue) {\n\t\t\t\tvalue._attached = eventClock;\n\t\t\t\tdom.addEventListener(\n\t\t\t\t\tname,\n\t\t\t\t\tuseCapture ? eventProxyCapture : eventProxy,\n\t\t\t\t\tuseCapture\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tvalue._attached = oldValue._attached;\n\t\t\t}\n\t\t} else {\n\t\t\tdom.removeEventListener(\n\t\t\t\tname,\n\t\t\t\tuseCapture ? eventProxyCapture : eventProxy,\n\t\t\t\tuseCapture\n\t\t\t);\n\t\t}\n\t} else {\n\t\tif (namespace == SVG_NAMESPACE) {\n\t\t\t// Normalize incorrect prop usage for SVG:\n\t\t\t// - xlink:href / xlinkHref --> href (xlink:href was removed from SVG and isn't needed)\n\t\t\t// - className --> class\n\t\t\tname = name.replace(/xlink(H|:h)/, 'h').replace(/sName$/, 's');\n\t\t} else if (\n\t\t\tname != 'width' &&\n\t\t\tname != 'height' &&\n\t\t\tname != 'href' &&\n\t\t\tname != 'list' &&\n\t\t\tname != 'form' &&\n\t\t\t// Default value in browsers is `-1` and an empty string is\n\t\t\t// cast to `0` instead\n\t\t\tname != 'tabIndex' &&\n\t\t\tname != 'download' &&\n\t\t\tname != 'rowSpan' &&\n\t\t\tname != 'colSpan' &&\n\t\t\tname != 'role' &&\n\t\t\tname != 'popover' &&\n\t\t\tname in dom\n\t\t) {\n\t\t\ttry {\n\t\t\t\tdom[name] = value == null ? '' : value;\n\t\t\t\t// labelled break is 1b smaller here than a return statement (sorry)\n\t\t\t\tbreak o;\n\t\t\t} catch (e) {}\n\t\t}\n\n\t\t// aria- and data- attributes have no boolean representation.\n\t\t// A `false` value is different from the attribute not being\n\t\t// present, so we can't remove it. For non-boolean aria\n\t\t// attributes we could treat false as a removal, but the\n\t\t// amount of exceptions would cost too many bytes. On top of\n\t\t// that other frameworks generally stringify `false`.\n\n\t\tif (typeof value == 'function') {\n\t\t\t// never serialize functions as attribute values\n\t\t} else if (value != null && (value !== false || name[4] == '-')) {\n\t\t\tdom.setAttribute(name, name == 'popover' && value == true ? '' : value);\n\t\t} else {\n\t\t\tdom.removeAttribute(name);\n\t\t}\n\t}\n}\n\n/**\n * Create an event proxy function.\n * @param {boolean} useCapture Is the event handler for the capture phase.\n * @private\n */\nfunction createEventProxy(useCapture) {\n\t/**\n\t * Proxy an event to hooked event handlers\n\t * @param {import('../internal').PreactEvent} e The event object from the browser\n\t * @private\n\t */\n\treturn function (e) {\n\t\tif (this._listeners) {\n\t\t\tconst eventHandler = this._listeners[e.type + useCapture];\n\t\t\tif (e._dispatched == null) {\n\t\t\t\te._dispatched = eventClock++;\n\n\t\t\t\t// When `e._dispatched` is smaller than the time when the targeted event\n\t\t\t\t// handler was attached we know we have bubbled up to an element that was added\n\t\t\t\t// during patching the DOM.\n\t\t\t} else if (e._dispatched < eventHandler._attached) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\treturn eventHandler(options.event ? options.event(e) : e);\n\t\t}\n\t};\n}\n\nconst eventProxy = createEventProxy(false);\nconst eventProxyCapture = createEventProxy(true);\n", "import { enqueueRender } from './component';\n\nexport let i = 0;\n\nexport function createContext(defaultValue, contextId) {\n\tcontextId = '__cC' + i++;\n\n\tconst context = {\n\t\t_id: contextId,\n\t\t_defaultValue: defaultValue,\n\t\t/** @type {import('./internal').FunctionComponent} */\n\t\tConsumer(props, contextValue) {\n\t\t\t// return props.children(\n\t\t\t// \tcontext[contextId] ? context[contextId].props.value : defaultValue\n\t\t\t// );\n\t\t\treturn props.children(contextValue);\n\t\t},\n\t\t/** @type {import('./internal').FunctionComponent} */\n\t\tProvider(props) {\n\t\t\tif (!this.getChildContext) {\n\t\t\t\t/** @type {Set | null} */\n\t\t\t\tlet subs = new Set();\n\t\t\t\tlet ctx = {};\n\t\t\t\tctx[contextId] = this;\n\n\t\t\t\tthis.getChildContext = () => ctx;\n\n\t\t\t\tthis.componentWillUnmount = () => {\n\t\t\t\t\tsubs = null;\n\t\t\t\t};\n\n\t\t\t\tthis.shouldComponentUpdate = function (_props) {\n\t\t\t\t\tif (this.props.value !== _props.value) {\n\t\t\t\t\t\tsubs.forEach(c => {\n\t\t\t\t\t\t\tc._force = true;\n\t\t\t\t\t\t\tenqueueRender(c);\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tthis.sub = c => {\n\t\t\t\t\tsubs.add(c);\n\t\t\t\t\tlet old = c.componentWillUnmount;\n\t\t\t\t\tc.componentWillUnmount = () => {\n\t\t\t\t\t\tif (subs) {\n\t\t\t\t\t\t\tsubs.delete(c);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (old) old.call(c);\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn props.children;\n\t\t}\n\t};\n\n\t// Devtools needs access to the context object when it\n\t// encounters a Provider. This is necessary to support\n\t// setting `displayName` on the context object instead\n\t// of on the component itself. See:\n\t// https://reactjs.org/docs/context.html#contextdisplayname\n\n\treturn (context.Provider._contextRef = context.Consumer.contextType =\n\t\tcontext);\n}\n", "import { diff, unmount, applyRef } from './index';\nimport { createVNode, Fragment } from '../create-element';\nimport {\n\tEMPTY_OBJ,\n\tEMPTY_ARR,\n\tINSERT_VNODE,\n\tMATCHED,\n\tUNDEFINED\n} from '../constants';\nimport { isArray } from '../util';\nimport { getDomSibling } from '../component';\n\n/**\n * @typedef {import('../internal').ComponentChildren} ComponentChildren\n * @typedef {import('../internal').Component} Component\n * @typedef {import('../internal').PreactElement} PreactElement\n * @typedef {import('../internal').VNode} VNode\n */\n\n/**\n * Diff the children of a virtual node\n * @param {PreactElement} parentDom The DOM element whose children are being\n * diffed\n * @param {ComponentChildren[]} renderResult\n * @param {VNode} newParentVNode The new virtual node whose children should be\n * diff'ed against oldParentVNode\n * @param {VNode} oldParentVNode The old virtual node whose children should be\n * diff'ed against newParentVNode\n * @param {object} globalContext The current context object - modified by\n * getChildContext\n * @param {string} namespace Current namespace of the DOM node (HTML, SVG, or MathML)\n * @param {Array} excessDomChildren\n * @param {Array} commitQueue List of components which have callbacks\n * to invoke in commitRoot\n * @param {PreactElement} oldDom The current attached DOM element any new dom\n * elements should be placed around. Likely `null` on first render (except when\n * hydrating). Can be a sibling DOM element when diffing Fragments that have\n * siblings. In most cases, it starts out as `oldChildren[0]._dom`.\n * @param {boolean} isHydrating Whether or not we are in hydration\n * @param {any[]} refQueue an array of elements needed to invoke refs\n */\nexport function diffChildren(\n\tparentDom,\n\trenderResult,\n\tnewParentVNode,\n\toldParentVNode,\n\tglobalContext,\n\tnamespace,\n\texcessDomChildren,\n\tcommitQueue,\n\toldDom,\n\tisHydrating,\n\trefQueue\n) {\n\tlet i,\n\t\t/** @type {VNode} */\n\t\toldVNode,\n\t\t/** @type {VNode} */\n\t\tchildVNode,\n\t\t/** @type {PreactElement} */\n\t\tnewDom,\n\t\t/** @type {PreactElement} */\n\t\tfirstChildDom;\n\n\t// This is a compression of oldParentVNode!=null && oldParentVNode != EMPTY_OBJ && oldParentVNode._children || EMPTY_ARR\n\t// as EMPTY_OBJ._children should be `undefined`.\n\t/** @type {VNode[]} */\n\tlet oldChildren = (oldParentVNode && oldParentVNode._children) || EMPTY_ARR;\n\n\tlet newChildrenLength = renderResult.length;\n\n\toldDom = constructNewChildrenArray(\n\t\tnewParentVNode,\n\t\trenderResult,\n\t\toldChildren,\n\t\toldDom,\n\t\tnewChildrenLength\n\t);\n\n\tfor (i = 0; i < newChildrenLength; i++) {\n\t\tchildVNode = newParentVNode._children[i];\n\t\tif (childVNode == null) continue;\n\n\t\t// At this point, constructNewChildrenArray has assigned _index to be the\n\t\t// matchingIndex for this VNode's oldVNode (or -1 if there is no oldVNode).\n\t\tif (childVNode._index === -1) {\n\t\t\toldVNode = EMPTY_OBJ;\n\t\t} else {\n\t\t\toldVNode = oldChildren[childVNode._index] || EMPTY_OBJ;\n\t\t}\n\n\t\t// Update childVNode._index to its final index\n\t\tchildVNode._index = i;\n\n\t\t// Morph the old element into the new one, but don't append it to the dom yet\n\t\tlet result = diff(\n\t\t\tparentDom,\n\t\t\tchildVNode,\n\t\t\toldVNode,\n\t\t\tglobalContext,\n\t\t\tnamespace,\n\t\t\texcessDomChildren,\n\t\t\tcommitQueue,\n\t\t\toldDom,\n\t\t\tisHydrating,\n\t\t\trefQueue\n\t\t);\n\n\t\t// Adjust DOM nodes\n\t\tnewDom = childVNode._dom;\n\t\tif (childVNode.ref && oldVNode.ref != childVNode.ref) {\n\t\t\tif (oldVNode.ref) {\n\t\t\t\tapplyRef(oldVNode.ref, null, childVNode);\n\t\t\t}\n\t\t\trefQueue.push(\n\t\t\t\tchildVNode.ref,\n\t\t\t\tchildVNode._component || newDom,\n\t\t\t\tchildVNode\n\t\t\t);\n\t\t}\n\n\t\tif (firstChildDom == null && newDom != null) {\n\t\t\tfirstChildDom = newDom;\n\t\t}\n\n\t\tif (\n\t\t\tchildVNode._flags & INSERT_VNODE ||\n\t\t\toldVNode._children === childVNode._children\n\t\t) {\n\t\t\toldDom = insert(childVNode, oldDom, parentDom);\n\t\t} else if (typeof childVNode.type == 'function' && result !== UNDEFINED) {\n\t\t\toldDom = result;\n\t\t} else if (newDom) {\n\t\t\toldDom = newDom.nextSibling;\n\t\t}\n\n\t\t// Unset diffing flags\n\t\tchildVNode._flags &= ~(INSERT_VNODE | MATCHED);\n\t}\n\n\tnewParentVNode._dom = firstChildDom;\n\n\treturn oldDom;\n}\n\n/**\n * @param {VNode} newParentVNode\n * @param {ComponentChildren[]} renderResult\n * @param {VNode[]} oldChildren\n */\nfunction constructNewChildrenArray(\n\tnewParentVNode,\n\trenderResult,\n\toldChildren,\n\toldDom,\n\tnewChildrenLength\n) {\n\t/** @type {number} */\n\tlet i;\n\t/** @type {VNode} */\n\tlet childVNode;\n\t/** @type {VNode} */\n\tlet oldVNode;\n\n\tlet oldChildrenLength = oldChildren.length,\n\t\tremainingOldChildren = oldChildrenLength;\n\n\tlet skew = 0;\n\n\tnewParentVNode._children = new Array(newChildrenLength);\n\tfor (i = 0; i < newChildrenLength; i++) {\n\t\t// @ts-expect-error We are reusing the childVNode variable to hold both the\n\t\t// pre and post normalized childVNode\n\t\tchildVNode = renderResult[i];\n\n\t\tif (\n\t\t\tchildVNode == null ||\n\t\t\ttypeof childVNode == 'boolean' ||\n\t\t\ttypeof childVNode == 'function'\n\t\t) {\n\t\t\tnewParentVNode._children[i] = null;\n\t\t\tcontinue;\n\t\t}\n\t\t// If this newVNode is being reused (e.g.
{reuse}{reuse}
) in the same diff,\n\t\t// or we are rendering a component (e.g. setState) copy the oldVNodes so it can have\n\t\t// it's own DOM & etc. pointers\n\t\telse if (\n\t\t\ttypeof childVNode == 'string' ||\n\t\t\ttypeof childVNode == 'number' ||\n\t\t\t// eslint-disable-next-line valid-typeof\n\t\t\ttypeof childVNode == 'bigint' ||\n\t\t\tchildVNode.constructor == String\n\t\t) {\n\t\t\tchildVNode = newParentVNode._children[i] = createVNode(\n\t\t\t\tnull,\n\t\t\t\tchildVNode,\n\t\t\t\tnull,\n\t\t\t\tnull,\n\t\t\t\tnull\n\t\t\t);\n\t\t} else if (isArray(childVNode)) {\n\t\t\tchildVNode = newParentVNode._children[i] = createVNode(\n\t\t\t\tFragment,\n\t\t\t\t{ children: childVNode },\n\t\t\t\tnull,\n\t\t\t\tnull,\n\t\t\t\tnull\n\t\t\t);\n\t\t} else if (childVNode.constructor === UNDEFINED && childVNode._depth > 0) {\n\t\t\t// VNode is already in use, clone it. This can happen in the following\n\t\t\t// scenario:\n\t\t\t// const reuse =
\n\t\t\t//
{reuse}{reuse}
\n\t\t\tchildVNode = newParentVNode._children[i] = createVNode(\n\t\t\t\tchildVNode.type,\n\t\t\t\tchildVNode.props,\n\t\t\t\tchildVNode.key,\n\t\t\t\tchildVNode.ref ? childVNode.ref : null,\n\t\t\t\tchildVNode._original\n\t\t\t);\n\t\t} else {\n\t\t\tchildVNode = newParentVNode._children[i] = childVNode;\n\t\t}\n\n\t\tconst skewedIndex = i + skew;\n\t\tchildVNode._parent = newParentVNode;\n\t\tchildVNode._depth = newParentVNode._depth + 1;\n\n\t\t// Temporarily store the matchingIndex on the _index property so we can pull\n\t\t// out the oldVNode in diffChildren. We'll override this to the VNode's\n\t\t// final index after using this property to get the oldVNode\n\t\tconst matchingIndex = (childVNode._index = findMatchingIndex(\n\t\t\tchildVNode,\n\t\t\toldChildren,\n\t\t\tskewedIndex,\n\t\t\tremainingOldChildren\n\t\t));\n\n\t\toldVNode = null;\n\t\tif (matchingIndex !== -1) {\n\t\t\toldVNode = oldChildren[matchingIndex];\n\t\t\tremainingOldChildren--;\n\t\t\tif (oldVNode) {\n\t\t\t\toldVNode._flags |= MATCHED;\n\t\t\t}\n\t\t}\n\n\t\t// Here, we define isMounting for the purposes of the skew diffing\n\t\t// algorithm. Nodes that are unsuspending are considered mounting and we detect\n\t\t// this by checking if oldVNode._original === null\n\t\tconst isMounting = oldVNode == null || oldVNode._original === null;\n\n\t\tif (isMounting) {\n\t\t\tif (matchingIndex == -1) {\n\t\t\t\tskew--;\n\t\t\t}\n\n\t\t\t// If we are mounting a DOM VNode, mark it for insertion\n\t\t\tif (typeof childVNode.type != 'function') {\n\t\t\t\tchildVNode._flags |= INSERT_VNODE;\n\t\t\t}\n\t\t} else if (matchingIndex != skewedIndex) {\n\t\t\t// When we move elements around i.e. [0, 1, 2] --> [1, 0, 2]\n\t\t\t// --> we diff 1, we find it at position 1 while our skewed index is 0 and our skew is 0\n\t\t\t// we set the skew to 1 as we found an offset.\n\t\t\t// --> we diff 0, we find it at position 0 while our skewed index is at 2 and our skew is 1\n\t\t\t// this makes us increase the skew again.\n\t\t\t// --> we diff 2, we find it at position 2 while our skewed index is at 4 and our skew is 2\n\t\t\t//\n\t\t\t// this becomes an optimization question where currently we see a 1 element offset as an insertion\n\t\t\t// or deletion i.e. we optimize for [0, 1, 2] --> [9, 0, 1, 2]\n\t\t\t// while a more than 1 offset we see as a swap.\n\t\t\t// We could probably build heuristics for having an optimized course of action here as well, but\n\t\t\t// might go at the cost of some bytes.\n\t\t\t//\n\t\t\t// If we wanted to optimize for i.e. only swaps we'd just do the last two code-branches and have\n\t\t\t// only the first item be a re-scouting and all the others fall in their skewed counter-part.\n\t\t\t// We could also further optimize for swaps\n\t\t\tif (matchingIndex == skewedIndex - 1) {\n\t\t\t\tskew--;\n\t\t\t} else if (matchingIndex == skewedIndex + 1) {\n\t\t\t\tskew++;\n\t\t\t} else {\n\t\t\t\tif (matchingIndex > skewedIndex) {\n\t\t\t\t\tskew--;\n\t\t\t\t} else {\n\t\t\t\t\tskew++;\n\t\t\t\t}\n\n\t\t\t\t// Move this VNode's DOM if the original index (matchingIndex) doesn't\n\t\t\t\t// match the new skew index (i + new skew)\n\t\t\t\t// In the former two branches we know that it matches after skewing\n\t\t\t\tchildVNode._flags |= INSERT_VNODE;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Remove remaining oldChildren if there are any. Loop forwards so that as we\n\t// unmount DOM from the beginning of the oldChildren, we can adjust oldDom to\n\t// point to the next child, which needs to be the first DOM node that won't be\n\t// unmounted.\n\tif (remainingOldChildren) {\n\t\tfor (i = 0; i < oldChildrenLength; i++) {\n\t\t\toldVNode = oldChildren[i];\n\t\t\tif (oldVNode != null && (oldVNode._flags & MATCHED) == 0) {\n\t\t\t\tif (oldVNode._dom == oldDom) {\n\t\t\t\t\toldDom = getDomSibling(oldVNode);\n\t\t\t\t}\n\n\t\t\t\tunmount(oldVNode, oldVNode);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn oldDom;\n}\n\n/**\n * @param {VNode} parentVNode\n * @param {PreactElement} oldDom\n * @param {PreactElement} parentDom\n * @returns {PreactElement}\n */\nfunction insert(parentVNode, oldDom, parentDom) {\n\t// Note: VNodes in nested suspended trees may be missing _children.\n\n\tif (typeof parentVNode.type == 'function') {\n\t\tlet children = parentVNode._children;\n\t\tfor (let i = 0; children && i < children.length; i++) {\n\t\t\tif (children[i]) {\n\t\t\t\t// If we enter this code path on sCU bailout, where we copy\n\t\t\t\t// oldVNode._children to newVNode._children, we need to update the old\n\t\t\t\t// children's _parent pointer to point to the newVNode (parentVNode\n\t\t\t\t// here).\n\t\t\t\tchildren[i]._parent = parentVNode;\n\t\t\t\toldDom = insert(children[i], oldDom, parentDom);\n\t\t\t}\n\t\t}\n\n\t\treturn oldDom;\n\t} else if (parentVNode._dom != oldDom) {\n\t\tif (oldDom && parentVNode.type && !parentDom.contains(oldDom)) {\n\t\t\toldDom = getDomSibling(parentVNode);\n\t\t}\n\t\tparentDom.insertBefore(parentVNode._dom, oldDom || null);\n\t\toldDom = parentVNode._dom;\n\t}\n\n\tdo {\n\t\toldDom = oldDom && oldDom.nextSibling;\n\t} while (oldDom != null && oldDom.nodeType == 8);\n\n\treturn oldDom;\n}\n\n/**\n * Flatten and loop through the children of a virtual node\n * @param {ComponentChildren} children The unflattened children of a virtual\n * node\n * @returns {VNode[]}\n */\nexport function toChildArray(children, out) {\n\tout = out || [];\n\tif (children == null || typeof children == 'boolean') {\n\t} else if (isArray(children)) {\n\t\tchildren.some(child => {\n\t\t\ttoChildArray(child, out);\n\t\t});\n\t} else {\n\t\tout.push(children);\n\t}\n\treturn out;\n}\n\n/**\n * @param {VNode} childVNode\n * @param {VNode[]} oldChildren\n * @param {number} skewedIndex\n * @param {number} remainingOldChildren\n * @returns {number}\n */\nfunction findMatchingIndex(\n\tchildVNode,\n\toldChildren,\n\tskewedIndex,\n\tremainingOldChildren\n) {\n\tconst key = childVNode.key;\n\tconst type = childVNode.type;\n\tlet oldVNode = oldChildren[skewedIndex];\n\n\t// We only need to perform a search if there are more children\n\t// (remainingOldChildren) to search. However, if the oldVNode we just looked\n\t// at skewedIndex was not already used in this diff, then there must be at\n\t// least 1 other (so greater than 1) remainingOldChildren to attempt to match\n\t// against. So the following condition checks that ensuring\n\t// remainingOldChildren > 1 if the oldVNode is not already used/matched. Else\n\t// if the oldVNode was null or matched, then there could needs to be at least\n\t// 1 (aka `remainingOldChildren > 0`) children to find and compare against.\n\t//\n\t// If there is an unkeyed functional VNode, that isn't a built-in like our Fragment,\n\t// we should not search as we risk re-using state of an unrelated VNode. (reverted for now)\n\tlet shouldSearch =\n\t\t// (typeof type != 'function' || type === Fragment || key) &&\n\t\tremainingOldChildren >\n\t\t(oldVNode != null && (oldVNode._flags & MATCHED) == 0 ? 1 : 0);\n\n\tif (\n\t\toldVNode === null ||\n\t\t(oldVNode &&\n\t\t\tkey == oldVNode.key &&\n\t\t\ttype === oldVNode.type &&\n\t\t\t(oldVNode._flags & MATCHED) == 0)\n\t) {\n\t\treturn skewedIndex;\n\t} else if (shouldSearch) {\n\t\tlet x = skewedIndex - 1;\n\t\tlet y = skewedIndex + 1;\n\t\twhile (x >= 0 || y < oldChildren.length) {\n\t\t\tif (x >= 0) {\n\t\t\t\toldVNode = oldChildren[x];\n\t\t\t\tif (\n\t\t\t\t\toldVNode &&\n\t\t\t\t\t(oldVNode._flags & MATCHED) == 0 &&\n\t\t\t\t\tkey == oldVNode.key &&\n\t\t\t\t\ttype === oldVNode.type\n\t\t\t\t) {\n\t\t\t\t\treturn x;\n\t\t\t\t}\n\t\t\t\tx--;\n\t\t\t}\n\n\t\t\tif (y < oldChildren.length) {\n\t\t\t\toldVNode = oldChildren[y];\n\t\t\t\tif (\n\t\t\t\t\toldVNode &&\n\t\t\t\t\t(oldVNode._flags & MATCHED) == 0 &&\n\t\t\t\t\tkey == oldVNode.key &&\n\t\t\t\t\ttype === oldVNode.type\n\t\t\t\t) {\n\t\t\t\t\treturn y;\n\t\t\t\t}\n\t\t\t\ty++;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn -1;\n}\n", "import {\n\tEMPTY_OBJ,\n\tMATH_NAMESPACE,\n\tMODE_HYDRATE,\n\tMODE_SUSPENDED,\n\tRESET_MODE,\n\tSVG_NAMESPACE,\n\tUNDEFINED,\n\tXHTML_NAMESPACE\n} from '../constants';\nimport { BaseComponent, getDomSibling } from '../component';\nimport { Fragment } from '../create-element';\nimport { diffChildren } from './children';\nimport { setProperty } from './props';\nimport { assign, isArray, removeNode, slice } from '../util';\nimport options from '../options';\n\n/**\n * @typedef {import('../internal').ComponentChildren} ComponentChildren\n * @typedef {import('../internal').Component} Component\n * @typedef {import('../internal').PreactElement} PreactElement\n * @typedef {import('../internal').VNode} VNode\n */\n\n/**\n * @template {any} T\n * @typedef {import('../internal').Ref} Ref\n */\n\n/**\n * Diff two virtual nodes and apply proper changes to the DOM\n * @param {PreactElement} parentDom The parent of the DOM element\n * @param {VNode} newVNode The new virtual node\n * @param {VNode} oldVNode The old virtual node\n * @param {object} globalContext The current context object. Modified by\n * getChildContext\n * @param {string} namespace Current namespace of the DOM node (HTML, SVG, or MathML)\n * @param {Array} excessDomChildren\n * @param {Array} commitQueue List of components which have callbacks\n * to invoke in commitRoot\n * @param {PreactElement} oldDom The current attached DOM element any new dom\n * elements should be placed around. Likely `null` on first render (except when\n * hydrating). Can be a sibling DOM element when diffing Fragments that have\n * siblings. In most cases, it starts out as `oldChildren[0]._dom`.\n * @param {boolean} isHydrating Whether or not we are in hydration\n * @param {any[]} refQueue an array of elements needed to invoke refs\n */\nexport function diff(\n\tparentDom,\n\tnewVNode,\n\toldVNode,\n\tglobalContext,\n\tnamespace,\n\texcessDomChildren,\n\tcommitQueue,\n\toldDom,\n\tisHydrating,\n\trefQueue\n) {\n\t/** @type {any} */\n\tlet tmp,\n\t\tnewType = newVNode.type;\n\n\t// When passing through createElement it assigns the object\n\t// constructor as undefined. This to prevent JSON-injection.\n\tif (newVNode.constructor !== UNDEFINED) return null;\n\n\t// If the previous diff bailed out, resume creating/hydrating.\n\tif (oldVNode._flags & MODE_SUSPENDED) {\n\t\tisHydrating = !!(oldVNode._flags & MODE_HYDRATE);\n\t\toldDom = newVNode._dom = oldVNode._dom;\n\t\texcessDomChildren = [oldDom];\n\t}\n\n\tif ((tmp = options._diff)) tmp(newVNode);\n\n\touter: if (typeof newType == 'function') {\n\t\ttry {\n\t\t\tlet c, isNew, oldProps, oldState, snapshot, clearProcessingException;\n\t\t\tlet newProps = newVNode.props;\n\t\t\tconst isClassComponent =\n\t\t\t\t'prototype' in newType && newType.prototype.render;\n\n\t\t\t// Necessary for createContext api. Setting this property will pass\n\t\t\t// the context value as `this.context` just for this component.\n\t\t\ttmp = newType.contextType;\n\t\t\tlet provider = tmp && globalContext[tmp._id];\n\t\t\tlet componentContext = tmp\n\t\t\t\t? provider\n\t\t\t\t\t? provider.props.value\n\t\t\t\t\t: tmp._defaultValue\n\t\t\t\t: globalContext;\n\n\t\t\t// Get component and set it to `c`\n\t\t\tif (oldVNode._component) {\n\t\t\t\tc = newVNode._component = oldVNode._component;\n\t\t\t\tclearProcessingException = c._processingException = c._pendingError;\n\t\t\t} else {\n\t\t\t\t// Instantiate the new component\n\t\t\t\tif (isClassComponent) {\n\t\t\t\t\t// @ts-expect-error The check above verifies that newType is suppose to be constructed\n\t\t\t\t\tnewVNode._component = c = new newType(newProps, componentContext); // eslint-disable-line new-cap\n\t\t\t\t} else {\n\t\t\t\t\t// @ts-expect-error Trust me, Component implements the interface we want\n\t\t\t\t\tnewVNode._component = c = new BaseComponent(\n\t\t\t\t\t\tnewProps,\n\t\t\t\t\t\tcomponentContext\n\t\t\t\t\t);\n\t\t\t\t\tc.constructor = newType;\n\t\t\t\t\tc.render = doRender;\n\t\t\t\t}\n\t\t\t\tif (provider) provider.sub(c);\n\n\t\t\t\tc.props = newProps;\n\t\t\t\tif (!c.state) c.state = {};\n\t\t\t\tc.context = componentContext;\n\t\t\t\tc._globalContext = globalContext;\n\t\t\t\tisNew = c._dirty = true;\n\t\t\t\tc._renderCallbacks = [];\n\t\t\t\tc._stateCallbacks = [];\n\t\t\t}\n\n\t\t\t// Invoke getDerivedStateFromProps\n\t\t\tif (isClassComponent && c._nextState == null) {\n\t\t\t\tc._nextState = c.state;\n\t\t\t}\n\n\t\t\tif (isClassComponent && newType.getDerivedStateFromProps != null) {\n\t\t\t\tif (c._nextState == c.state) {\n\t\t\t\t\tc._nextState = assign({}, c._nextState);\n\t\t\t\t}\n\n\t\t\t\tassign(\n\t\t\t\t\tc._nextState,\n\t\t\t\t\tnewType.getDerivedStateFromProps(newProps, c._nextState)\n\t\t\t\t);\n\t\t\t}\n\n\t\t\toldProps = c.props;\n\t\t\toldState = c.state;\n\t\t\tc._vnode = newVNode;\n\n\t\t\t// Invoke pre-render lifecycle methods\n\t\t\tif (isNew) {\n\t\t\t\tif (\n\t\t\t\t\tisClassComponent &&\n\t\t\t\t\tnewType.getDerivedStateFromProps == null &&\n\t\t\t\t\tc.componentWillMount != null\n\t\t\t\t) {\n\t\t\t\t\tc.componentWillMount();\n\t\t\t\t}\n\n\t\t\t\tif (isClassComponent && c.componentDidMount != null) {\n\t\t\t\t\tc._renderCallbacks.push(c.componentDidMount);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (\n\t\t\t\t\tisClassComponent &&\n\t\t\t\t\tnewType.getDerivedStateFromProps == null &&\n\t\t\t\t\tnewProps !== oldProps &&\n\t\t\t\t\tc.componentWillReceiveProps != null\n\t\t\t\t) {\n\t\t\t\t\tc.componentWillReceiveProps(newProps, componentContext);\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\t!c._force &&\n\t\t\t\t\t((c.shouldComponentUpdate != null &&\n\t\t\t\t\t\tc.shouldComponentUpdate(\n\t\t\t\t\t\t\tnewProps,\n\t\t\t\t\t\t\tc._nextState,\n\t\t\t\t\t\t\tcomponentContext\n\t\t\t\t\t\t) === false) ||\n\t\t\t\t\t\tnewVNode._original == oldVNode._original)\n\t\t\t\t) {\n\t\t\t\t\t// More info about this here: https://gist.github.com/JoviDeCroock/bec5f2ce93544d2e6070ef8e0036e4e8\n\t\t\t\t\tif (newVNode._original != oldVNode._original) {\n\t\t\t\t\t\t// When we are dealing with a bail because of sCU we have to update\n\t\t\t\t\t\t// the props, state and dirty-state.\n\t\t\t\t\t\t// when we are dealing with strict-equality we don't as the child could still\n\t\t\t\t\t\t// be dirtied see #3883\n\t\t\t\t\t\tc.props = newProps;\n\t\t\t\t\t\tc.state = c._nextState;\n\t\t\t\t\t\tc._dirty = false;\n\t\t\t\t\t}\n\n\t\t\t\t\tnewVNode._dom = oldVNode._dom;\n\t\t\t\t\tnewVNode._children = oldVNode._children;\n\t\t\t\t\tnewVNode._children.some(vnode => {\n\t\t\t\t\t\tif (vnode) vnode._parent = newVNode;\n\t\t\t\t\t});\n\n\t\t\t\t\tfor (let i = 0; i < c._stateCallbacks.length; i++) {\n\t\t\t\t\t\tc._renderCallbacks.push(c._stateCallbacks[i]);\n\t\t\t\t\t}\n\t\t\t\t\tc._stateCallbacks = [];\n\n\t\t\t\t\tif (c._renderCallbacks.length) {\n\t\t\t\t\t\tcommitQueue.push(c);\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak outer;\n\t\t\t\t}\n\n\t\t\t\tif (c.componentWillUpdate != null) {\n\t\t\t\t\tc.componentWillUpdate(newProps, c._nextState, componentContext);\n\t\t\t\t}\n\n\t\t\t\tif (isClassComponent && c.componentDidUpdate != null) {\n\t\t\t\t\tc._renderCallbacks.push(() => {\n\t\t\t\t\t\tc.componentDidUpdate(oldProps, oldState, snapshot);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tc.context = componentContext;\n\t\t\tc.props = newProps;\n\t\t\tc._parentDom = parentDom;\n\t\t\tc._force = false;\n\n\t\t\tlet renderHook = options._render,\n\t\t\t\tcount = 0;\n\t\t\tif (isClassComponent) {\n\t\t\t\tc.state = c._nextState;\n\t\t\t\tc._dirty = false;\n\n\t\t\t\tif (renderHook) renderHook(newVNode);\n\n\t\t\t\ttmp = c.render(c.props, c.state, c.context);\n\n\t\t\t\tfor (let i = 0; i < c._stateCallbacks.length; i++) {\n\t\t\t\t\tc._renderCallbacks.push(c._stateCallbacks[i]);\n\t\t\t\t}\n\t\t\t\tc._stateCallbacks = [];\n\t\t\t} else {\n\t\t\t\tdo {\n\t\t\t\t\tc._dirty = false;\n\t\t\t\t\tif (renderHook) renderHook(newVNode);\n\n\t\t\t\t\ttmp = c.render(c.props, c.state, c.context);\n\n\t\t\t\t\t// Handle setState called in render, see #2553\n\t\t\t\t\tc.state = c._nextState;\n\t\t\t\t} while (c._dirty && ++count < 25);\n\t\t\t}\n\n\t\t\t// Handle setState called in render, see #2553\n\t\t\tc.state = c._nextState;\n\n\t\t\tif (c.getChildContext != null) {\n\t\t\t\tglobalContext = assign(assign({}, globalContext), c.getChildContext());\n\t\t\t}\n\n\t\t\tif (isClassComponent && !isNew && c.getSnapshotBeforeUpdate != null) {\n\t\t\t\tsnapshot = c.getSnapshotBeforeUpdate(oldProps, oldState);\n\t\t\t}\n\n\t\t\tlet isTopLevelFragment =\n\t\t\t\ttmp != null && tmp.type === Fragment && tmp.key == null;\n\t\t\tlet renderResult = isTopLevelFragment ? tmp.props.children : tmp;\n\n\t\t\toldDom = diffChildren(\n\t\t\t\tparentDom,\n\t\t\t\tisArray(renderResult) ? renderResult : [renderResult],\n\t\t\t\tnewVNode,\n\t\t\t\toldVNode,\n\t\t\t\tglobalContext,\n\t\t\t\tnamespace,\n\t\t\t\texcessDomChildren,\n\t\t\t\tcommitQueue,\n\t\t\t\toldDom,\n\t\t\t\tisHydrating,\n\t\t\t\trefQueue\n\t\t\t);\n\n\t\t\tc.base = newVNode._dom;\n\n\t\t\t// We successfully rendered this VNode, unset any stored hydration/bailout state:\n\t\t\tnewVNode._flags &= RESET_MODE;\n\n\t\t\tif (c._renderCallbacks.length) {\n\t\t\t\tcommitQueue.push(c);\n\t\t\t}\n\n\t\t\tif (clearProcessingException) {\n\t\t\t\tc._pendingError = c._processingException = null;\n\t\t\t}\n\t\t} catch (e) {\n\t\t\tnewVNode._original = null;\n\t\t\t// if hydrating or creating initial tree, bailout preserves DOM:\n\t\t\tif (isHydrating || excessDomChildren != null) {\n\t\t\t\tif (e.then) {\n\t\t\t\t\tnewVNode._flags |= isHydrating\n\t\t\t\t\t\t? MODE_HYDRATE | MODE_SUSPENDED\n\t\t\t\t\t\t: MODE_SUSPENDED;\n\n\t\t\t\t\twhile (oldDom && oldDom.nodeType == 8 && oldDom.nextSibling) {\n\t\t\t\t\t\toldDom = oldDom.nextSibling;\n\t\t\t\t\t}\n\n\t\t\t\t\texcessDomChildren[excessDomChildren.indexOf(oldDom)] = null;\n\t\t\t\t\tnewVNode._dom = oldDom;\n\t\t\t\t} else {\n\t\t\t\t\tfor (let i = excessDomChildren.length; i--; ) {\n\t\t\t\t\t\tremoveNode(excessDomChildren[i]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tnewVNode._dom = oldVNode._dom;\n\t\t\t\tnewVNode._children = oldVNode._children;\n\t\t\t}\n\t\t\toptions._catchError(e, newVNode, oldVNode);\n\t\t}\n\t} else if (\n\t\texcessDomChildren == null &&\n\t\tnewVNode._original == oldVNode._original\n\t) {\n\t\tnewVNode._children = oldVNode._children;\n\t\tnewVNode._dom = oldVNode._dom;\n\t} else {\n\t\toldDom = newVNode._dom = diffElementNodes(\n\t\t\toldVNode._dom,\n\t\t\tnewVNode,\n\t\t\toldVNode,\n\t\t\tglobalContext,\n\t\t\tnamespace,\n\t\t\texcessDomChildren,\n\t\t\tcommitQueue,\n\t\t\tisHydrating,\n\t\t\trefQueue\n\t\t);\n\t}\n\n\tif ((tmp = options.diffed)) tmp(newVNode);\n\n\treturn newVNode._flags & MODE_SUSPENDED ? undefined : oldDom;\n}\n\n/**\n * @param {Array} commitQueue List of components\n * which have callbacks to invoke in commitRoot\n * @param {VNode} root\n */\nexport function commitRoot(commitQueue, root, refQueue) {\n\tfor (let i = 0; i < refQueue.length; i++) {\n\t\tapplyRef(refQueue[i], refQueue[++i], refQueue[++i]);\n\t}\n\n\tif (options._commit) options._commit(root, commitQueue);\n\n\tcommitQueue.some(c => {\n\t\ttry {\n\t\t\t// @ts-expect-error Reuse the commitQueue variable here so the type changes\n\t\t\tcommitQueue = c._renderCallbacks;\n\t\t\tc._renderCallbacks = [];\n\t\t\tcommitQueue.some(cb => {\n\t\t\t\t// @ts-expect-error See above comment on commitQueue\n\t\t\t\tcb.call(c);\n\t\t\t});\n\t\t} catch (e) {\n\t\t\toptions._catchError(e, c._vnode);\n\t\t}\n\t});\n}\n\n/**\n * Diff two virtual nodes representing DOM element\n * @param {PreactElement} dom The DOM element representing the virtual nodes\n * being diffed\n * @param {VNode} newVNode The new virtual node\n * @param {VNode} oldVNode The old virtual node\n * @param {object} globalContext The current context object\n * @param {string} namespace Current namespace of the DOM node (HTML, SVG, or MathML)\n * @param {Array} excessDomChildren\n * @param {Array} commitQueue List of components which have callbacks\n * to invoke in commitRoot\n * @param {boolean} isHydrating Whether or not we are in hydration\n * @param {any[]} refQueue an array of elements needed to invoke refs\n * @returns {PreactElement}\n */\nfunction diffElementNodes(\n\tdom,\n\tnewVNode,\n\toldVNode,\n\tglobalContext,\n\tnamespace,\n\texcessDomChildren,\n\tcommitQueue,\n\tisHydrating,\n\trefQueue\n) {\n\tlet oldProps = oldVNode.props;\n\tlet newProps = newVNode.props;\n\tlet nodeType = /** @type {string} */ (newVNode.type);\n\t/** @type {any} */\n\tlet i;\n\t/** @type {{ __html?: string }} */\n\tlet newHtml;\n\t/** @type {{ __html?: string }} */\n\tlet oldHtml;\n\t/** @type {ComponentChildren} */\n\tlet newChildren;\n\tlet value;\n\tlet inputValue;\n\tlet checked;\n\n\t// Tracks entering and exiting namespaces when descending through the tree.\n\tif (nodeType == 'svg') namespace = SVG_NAMESPACE;\n\telse if (nodeType == 'math') namespace = MATH_NAMESPACE;\n\telse if (!namespace) namespace = XHTML_NAMESPACE;\n\n\tif (excessDomChildren != null) {\n\t\tfor (i = 0; i < excessDomChildren.length; i++) {\n\t\t\tvalue = excessDomChildren[i];\n\n\t\t\t// if newVNode matches an element in excessDomChildren or the `dom`\n\t\t\t// argument matches an element in excessDomChildren, remove it from\n\t\t\t// excessDomChildren so it isn't later removed in diffChildren\n\t\t\tif (\n\t\t\t\tvalue &&\n\t\t\t\t'setAttribute' in value == !!nodeType &&\n\t\t\t\t(nodeType ? value.localName == nodeType : value.nodeType == 3)\n\t\t\t) {\n\t\t\t\tdom = value;\n\t\t\t\texcessDomChildren[i] = null;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (dom == null) {\n\t\tif (nodeType == null) {\n\t\t\treturn document.createTextNode(newProps);\n\t\t}\n\n\t\tdom = document.createElementNS(\n\t\t\tnamespace,\n\t\t\tnodeType,\n\t\t\tnewProps.is && newProps\n\t\t);\n\n\t\t// we are creating a new node, so we can assume this is a new subtree (in\n\t\t// case we are hydrating), this deopts the hydrate\n\t\tif (isHydrating) {\n\t\t\tif (options._hydrationMismatch)\n\t\t\t\toptions._hydrationMismatch(newVNode, excessDomChildren);\n\t\t\tisHydrating = false;\n\t\t}\n\t\t// we created a new parent, so none of the previously attached children can be reused:\n\t\texcessDomChildren = null;\n\t}\n\n\tif (nodeType === null) {\n\t\t// During hydration, we still have to split merged text from SSR'd HTML.\n\t\tif (oldProps !== newProps && (!isHydrating || dom.data !== newProps)) {\n\t\t\tdom.data = newProps;\n\t\t}\n\t} else {\n\t\t// If excessDomChildren was not null, repopulate it with the current element's children:\n\t\texcessDomChildren = excessDomChildren && slice.call(dom.childNodes);\n\n\t\toldProps = oldVNode.props || EMPTY_OBJ;\n\n\t\t// If we are in a situation where we are not hydrating but are using\n\t\t// existing DOM (e.g. replaceNode) we should read the existing DOM\n\t\t// attributes to diff them\n\t\tif (!isHydrating && excessDomChildren != null) {\n\t\t\toldProps = {};\n\t\t\tfor (i = 0; i < dom.attributes.length; i++) {\n\t\t\t\tvalue = dom.attributes[i];\n\t\t\t\toldProps[value.name] = value.value;\n\t\t\t}\n\t\t}\n\n\t\tfor (i in oldProps) {\n\t\t\tvalue = oldProps[i];\n\t\t\tif (i == 'children') {\n\t\t\t} else if (i == 'dangerouslySetInnerHTML') {\n\t\t\t\toldHtml = value;\n\t\t\t} else if (!(i in newProps)) {\n\t\t\t\tif (\n\t\t\t\t\t(i == 'value' && 'defaultValue' in newProps) ||\n\t\t\t\t\t(i == 'checked' && 'defaultChecked' in newProps)\n\t\t\t\t) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tsetProperty(dom, i, null, value, namespace);\n\t\t\t}\n\t\t}\n\n\t\t// During hydration, props are not diffed at all (including dangerouslySetInnerHTML)\n\t\t// @TODO we should warn in debug mode when props don't match here.\n\t\tfor (i in newProps) {\n\t\t\tvalue = newProps[i];\n\t\t\tif (i == 'children') {\n\t\t\t\tnewChildren = value;\n\t\t\t} else if (i == 'dangerouslySetInnerHTML') {\n\t\t\t\tnewHtml = value;\n\t\t\t} else if (i == 'value') {\n\t\t\t\tinputValue = value;\n\t\t\t} else if (i == 'checked') {\n\t\t\t\tchecked = value;\n\t\t\t} else if (\n\t\t\t\t(!isHydrating || typeof value == 'function') &&\n\t\t\t\toldProps[i] !== value\n\t\t\t) {\n\t\t\t\tsetProperty(dom, i, value, oldProps[i], namespace);\n\t\t\t}\n\t\t}\n\n\t\t// If the new vnode didn't have dangerouslySetInnerHTML, diff its children\n\t\tif (newHtml) {\n\t\t\t// Avoid re-applying the same '__html' if it did not changed between re-render\n\t\t\tif (\n\t\t\t\t!isHydrating &&\n\t\t\t\t(!oldHtml ||\n\t\t\t\t\t(newHtml.__html !== oldHtml.__html &&\n\t\t\t\t\t\tnewHtml.__html !== dom.innerHTML))\n\t\t\t) {\n\t\t\t\tdom.innerHTML = newHtml.__html;\n\t\t\t}\n\n\t\t\tnewVNode._children = [];\n\t\t} else {\n\t\t\tif (oldHtml) dom.innerHTML = '';\n\n\t\t\tdiffChildren(\n\t\t\t\tdom,\n\t\t\t\tisArray(newChildren) ? newChildren : [newChildren],\n\t\t\t\tnewVNode,\n\t\t\t\toldVNode,\n\t\t\t\tglobalContext,\n\t\t\t\tnodeType == 'foreignObject' ? XHTML_NAMESPACE : namespace,\n\t\t\t\texcessDomChildren,\n\t\t\t\tcommitQueue,\n\t\t\t\texcessDomChildren\n\t\t\t\t\t? excessDomChildren[0]\n\t\t\t\t\t: oldVNode._children && getDomSibling(oldVNode, 0),\n\t\t\t\tisHydrating,\n\t\t\t\trefQueue\n\t\t\t);\n\n\t\t\t// Remove children that are not part of any vnode.\n\t\t\tif (excessDomChildren != null) {\n\t\t\t\tfor (i = excessDomChildren.length; i--; ) {\n\t\t\t\t\tremoveNode(excessDomChildren[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// As above, don't diff props during hydration\n\t\tif (!isHydrating) {\n\t\t\ti = 'value';\n\t\t\tif (nodeType == 'progress' && inputValue == null) {\n\t\t\t\tdom.removeAttribute('value');\n\t\t\t} else if (\n\t\t\t\tinputValue !== UNDEFINED &&\n\t\t\t\t// #2756 For the -element the initial value is 0,\n\t\t\t\t// despite the attribute not being present. When the attribute\n\t\t\t\t// is missing the progress bar is treated as indeterminate.\n\t\t\t\t// To fix that we'll always update it when it is 0 for progress elements\n\t\t\t\t(inputValue !== dom[i] ||\n\t\t\t\t\t(nodeType == 'progress' && !inputValue) ||\n\t\t\t\t\t// This is only for IE 11 to fix \n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t\t{getText(\"advancedOptions\")}\n\t\t\t\t\t\t\n\t\t\t\t\t\t{typeof overwrites.userID === \"undefined\" && (\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{typeof overwrites.problemID === \"undefined\" && (\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{typeof overwrites.problemListID === \"undefined\" && (\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{typeof overwrites.contestID === \"undefined\" && (\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t\n\t\t\t
\n\t\t\t\t{typeof props.title !== \"undefined\" &&

{props.title}

}\n\t\t\t\t{!initialLoad && (\n\t\t\t\t\t<>\n\t\t\t\t\t\t

{rezStr(count, truncatedCount)}

\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t{count > 0 ? (\n\t\t\t\t\t\t\t\t {\n\t\t\t\t\t\t\t\t\t\tsetQuery({ ...query, page: num }, true);\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\tctxSize={2}\n\t\t\t\t\t\t\t\t\tshowArrows={true}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t) : typeof subs !== \"undefined\" && subs.submissions.length > 0 ? (\n\t\t\t\t\t\t\t\t {}} ctxSize={2} showArrows={true} />\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t)}\n\t\t\t\t{!loading &&\n\t\t\t\t\ttypeof overwrites.problemID === \"undefined\" &&\n\t\t\t\t\tquery.problem_id != null &&\n\t\t\t\t\tquery.problem_id > 0 &&\n\t\t\t\t\ttypeof subs !== \"undefined\" &&\n\t\t\t\t\tObject.keys(subs.problems).length > 0 && (\n\t\t\t\t\t\t

\n\t\t\t\t\t\t\t{getText(\"problemSingle\")}{\" \"}\n\t\t\t\t\t\t\t{subs.problems[Object.keys(subs.problems)[0]].name}\n\t\t\t\t\t\t

\n\t\t\t\t\t)}\n\t\t\t\t{initialLoad ? (\n\t\t\t\t\t<>\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t) : typeof subs !== \"undefined\" && subs.submissions.length > 0 ? (\n\t\t\t\t\t
\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t{((query.problem_id == 0 || query.problem_id == null) && ) || (\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t{loading ? (\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t{subs.submissions.map((sub) => (\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t{((query.problem_id == 0 || query.problem_id == null) && (\n\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t)) || (\n\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t{status(sub, subs.problems[sub.problem_id])}\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t{getText(\"id\")}\n\t\t\t\t\t\t\t\t\t{getText(\"author\")} doSort(\"id\")}>\n\t\t\t\t\t\t\t\t\t\t{getText(\"uploadDate\")} {sortIndicator(\"id\")}\n\t\t\t\t\t\t\t\t\t{getText(\"problemSingle\")} doSort(\"code_size\")}>\n\t\t\t\t\t\t\t\t\t\t\t{getText(\"codeSize\")} {sortIndicator(\"code_size\")}\n\t\t\t\t\t\t\t\t\t\t doSort(\"max_time\")}>\n\t\t\t\t\t\t\t\t\t\t{getText(\"time\")} {sortIndicator(\"max_time\")}\n\t\t\t\t\t\t\t\t\t doSort(\"max_mem\")}>\n\t\t\t\t\t\t\t\t\t\t{getText(\"memory\")} {sortIndicator(\"max_mem\")}\n\t\t\t\t\t\t\t\t\t doSort(\"score\")}>\n\t\t\t\t\t\t\t\t\t\t{getText(\"status\")} {sortIndicator(\"score\")}\n\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t
\n\t\t\t\t\t\t\t\t\t\t\t\t{sub.id}\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t{subs.users[sub.user_id].name}\n\t\t\t\t\t\t\t\t\t\t\t{dayjs(sub.created_at).format(\"DD/MM/YYYY HH:mm\")}\n\t\t\t\t\t\t\t\t\t\t\t\t\t{subs.problems[sub.problem_id] ? (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{subs!.problems[sub.problem_id].name}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<>-\n\t\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t{sub.code_size > 0 ? sizeFormatter(sub.code_size) : \"-\"}\n\t\t\t\t\t\t\t\t\t\t\t\t{sub.max_time == -1 ? \"-\" : Math.floor(sub.max_time * 1000) + \"ms\"}{sub.max_memory == -1 ? \"-\" : sizeFormatter(sub.max_memory * 1024)}
\n\t\t\t\t\t
\n\t\t\t\t) : (\n\t\t\t\t\t
{getText(\"noSubFound\")}
\n\t\t\t\t)}\n\t\t\t
\n\t\t
\n\t);\n}\n\nregister(SubsView, \"kn-sub-viewer\", [\"problemid\", \"userid\", \"contestid\", \"title\"]);\n\nexport { SubsView };\n", "import {Fragment, h, render} from \"preact\";\nimport {useEffect, useRef, useState} from \"preact/hooks\";\nimport getText from \"../translation\";\n\nexport function KNModal({\n\t open,\n\t title,\n\t children,\n\t footer,\n\t closeCallback,\n\t large = true,\n }: {\n\topen: boolean;\n\ttitle: any;\n\tchildren?: preact.ComponentChildren;\n\tfooter?: preact.ComponentChildren;\n\tcloseCallback?: () => void;\n\tlarge?: boolean;\n}) {\n\tlet [lastState, setLastState] = useState(null);\n\tlet ref = useRef(null);\n\n\tuseEffect(() => {\n\t\tif (open == lastState) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (open) {\n\t\t\tref.current?.showModal();\n\t\t} else {\n\t\t\tref.current?.close();\n\t\t}\n\n\t\tsetLastState(open);\n\t\treturn () => {\n\t\t\tref.current?.close();\n\t\t};\n\t}, [open]);\n\n\treturn (\n\t\t\n\t\t\t
\n\t\t\t\t

{title}

\n\t\t\t\t
\n\t\t\t\t\t\n\t\t\t\t
\n\t\t\t
\n\t\t\t
{children}
\n\t\t\t{typeof footer !== \"undefined\" &&
{footer}
}\n\t\t
\n\t);\n}\n\nexport function confirm(message: string): Promise {\n\treturn new Promise((resolve) => {\n\t\tconst par = document.createElement(\"div\");\n\t\tdocument.getElementById(\"modals\")!.append(par);\n\n\t\tfunction callback(val: boolean) {\n\t\t\tpar.parentElement?.removeChild(par);\n\t\t\tresolve(val);\n\t\t}\n\n\t\trender(\n\t\t\t callback(false)}\n\t\t\t\tfooter={\n\t\t\t\t\t<>\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t}\n\t\t\t\tlarge={false}\n\t\t\t>\n\t\t\t\t

{message}

\n\t\t\t,\n\t\t\tpar\n\t\t);\n\t});\n}\n\n\ndocument.addEventListener(\"htmx:confirm\", e => {\n\tif (!e.detail.target.hasAttribute(\"hx-confirm\")) return\n\n\te.preventDefault();\n\tconfirm(e.detail.question).then(ok => {\n\t\tif (ok) e.detail.issueRequest(true);\n\t})\n})\n\ndocument.addEventListener(\"DOMContentLoaded\", e => {\n\tconst observer = new MutationObserver(records => {\n\t\tfor (let record of records) {\n\t\t\tfor (let node of record.addedNodes) {\n\t\t\t\tif (node instanceof HTMLDialogElement) {\n\t\t\t\t\tnode.showModal();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t})\n\tobserver.observe(document.getElementById(\"modals\")!, {childList: true})\n})\n\n", "import { h, Fragment, render } from \"preact\";\nimport { useEffect, useState } from \"preact/hooks\";\nimport register from \"preact-custom-element\";\nimport getText from \"../translation\";\nimport { apiToast } from \"../toast\";\nimport { BigSpinner, formatScoreStr } from \"./common\";\nimport { getCall } from \"../api/client\";\nimport { SubTask, TestTable } from \"./sub_mgr\";\nimport { KNModal } from \"./modal\";\n\ntype BreakdownResult = {\n\tmax_score: number;\n\tproblem: Problem;\n\tsubtasks: SubmissionSubTask[];\n\tsubtests: SubTest[];\n\tproblem_editor: boolean;\n};\n\nexport function MaxScoreBreakdown({ problemID, userID, contestID }: { problemID: number; userID?: number; contestID?: number }) {\n\tlet [subtasks, setSubtasks] = useState([]);\n\tlet [subtests, setSubtests] = useState(null);\n\tlet [loading, setLoading] = useState(true);\n\tlet [problem, setProblem] = useState(null);\n\tlet [maxScore, setMaxScore] = useState(-1);\n\tlet [problemEditor, setProblemEditor] = useState(false);\n\n\tasync function loadBreakdown() {\n\t\tconst rez = await getCall(`/problem/${problemID}/maxScoreBreakdown`, { userID, contestID });\n\t\tif (rez.status === \"error\") {\n\t\t\tapiToast(rez);\n\t\t\treturn;\n\t\t}\n\t\tsetMaxScore(rez.data.max_score);\n\t\tsetProblem(rez.data.problem);\n\t\tsetSubtasks(rez.data.subtasks);\n\t\tsetSubtests(rez.data.subtests);\n\t\tsetProblemEditor(rez.data.problem_editor);\n\t}\n\n\tuseEffect(() => {\n\t\tsetLoading(true);\n\t\tloadBreakdown()\n\t\t\t.then(() => setLoading(false))\n\t\t\t.catch(console.error);\n\t}, [problemID, userID, contestID]);\n\n\tif (!(subtests != null && problem != null && !loading)) {\n\t\treturn ;\n\t}\n\n\tlet content = <>{getText(\"score_breakdown_unattempted\")};\n\tif (maxScore >= 0) {\n\t\tcontent = (\n\t\t\t<>\n\t\t\t\t{[\"max_submission\", \"acm-icpc\"].includes(problem.scoring_strategy) && subtests.length > 0 && (\n\t\t\t\t\t

\n\t\t\t\t\t\t{getText(\"sub\")} {`#${subtests[0].submission_id}`}\n\t\t\t\t\t

\n\t\t\t\t)}\n\t\t\t\t
\n\t\t\t\t\t{subtasks.map((subtask) => (\n\t\t\t\t\t\t\n\t\t\t\t\t))}\n\t\t\t\t
\n\t\t\t\t{[\"max_submission\", \"acm-icpc\"].includes(problem.scoring_strategy) && (\n\t\t\t\t\t\n\t\t\t\t)}\n\t\t\t\n\t\t);\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t

\n\t\t\t\t{getText(\"problemSingle\")}{\" \"}\n\t\t\t\t{problem.name}:{\" \"}\n\t\t\t\t{maxScore >= 0 ? `${formatScoreStr(maxScore.toFixed(problem?.score_precision ?? 0))}p` : `0p`}\n\t\t\t

\n\n\t\t\t{content}\n\t\t\n\t);\n}\n\nfunction MaxScoreBreakdownDOM({ problemid, userid, contestid }: { problemid: string; userid?: string; contestid?: string }) {\n\tconst problemID = parseInt(problemid);\n\tif (isNaN(problemID)) {\n\t\tthrow new Error(\"Invalid problem ID\");\n\t}\n\tconst userID = parseInt(userid ?? \"asdf\");\n\tconst contestID = parseInt(contestid ?? \"asdf\");\n\treturn (\n\t\t\n\t\t\t\n\t\t\n\t);\n}\n\nregister(MaxScoreBreakdownDOM, \"kn-score-breakdown\", [\"problemid\", \"userid\", \"contestid\"]);\n\nexport function buildScoreBreakdownModal(problemID: number, contestID: number | undefined = undefined, userID: number | undefined = undefined) {\n\tconst val = document.getElementById(\"max_score_preact\");\n\tif (val != null) {\n\t\tdocument.getElementById(\"modals\")!.removeChild(val);\n\t}\n\tconst newVal = document.createElement(\"kn-score-breakdown\");\n\tnewVal.id = \"max_score_preact\";\n\tnewVal.setAttribute(\"problemid\", problemID.toString());\n\tif (typeof contestID !== \"undefined\") {\n\t\tnewVal.setAttribute(\"contestid\", contestID.toString());\n\t}\n\tif (typeof userID !== \"undefined\") {\n\t\tnewVal.setAttribute(\"userid\", userID.toString());\n\t}\n\n\tdocument.getElementById(\"modals\")!.appendChild(newVal);\n}\n\ndocument.addEventListener(\"DOMContentLoaded\", () => {\n\tArray.from(document.getElementsByClassName(\"max_score_breakdown\")).forEach((val) => {\n\t\tval.addEventListener(\"click\", (e) => {\n\t\t\te.preventDefault();\n\t\t\tif (e.currentTarget == null) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tlet problemID = parseInt((e.currentTarget as HTMLElement).dataset.problemid ?? \"asd\");\n\t\t\tif (isNaN(problemID)) {\n\t\t\t\tapiToast({ status: \"error\", data: \"Invalid problem id for max score modal\" });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tlet contestID: number | undefined = parseInt((e.currentTarget as HTMLElement).dataset.contestid ?? \"asd\");\n\t\t\tif (isNaN(contestID)) {\n\t\t\t\tcontestID = undefined;\n\t\t\t}\n\t\t\tbuildScoreBreakdownModal(problemID, contestID);\n\t\t});\n\t});\n});\n", "import dayjs, { Dayjs } from \"dayjs\";\nimport getText from \"./translation\";\nimport { sprintf } from \"sprintf-js\";\n\nlet diffMilli: number = -1;\n\nexport function initTime(nowTime: Dayjs, serverTime: Dayjs) {\n\tdiffMilli = nowTime.diff(serverTime, \"milliseconds\", true);\n\tconsole.log(`Client-Server time difference: ${diffMilli}ms`);\n}\n\nexport function serverTime(): Dayjs {\n\treturn dayjs().subtract(diffMilli, \"millisecond\");\n}\n\n// targetTime can be:\n// - a Dayjs object, in which case the duration is computed at the moment of the function call\n// - a number, representing the number of seconds to format\nexport function formatDuration(targetTime: Dayjs | number, hideSeconds: boolean = false, showFull: boolean = false): string {\n\t// NOTE: dayjs diff must take into consideration diffMilli from initTime (to compute server duration)\n\t// If user has clock forwards or backwards he will get the wrong time in this current implementation.\n\tlet diff = -1;\n\tif (typeof targetTime == \"number\") {\n\t\tdiff = Math.floor(targetTime);\n\t} else {\n\t\tdiff = targetTime.diff(serverTime(), \"s\");\n\t}\n\tif (diff < 0) {\n\t\tif (!showFull) {\n\t\t\treturn getText(\"time_elapsed\");\n\t\t} else {\n\t\t\treturn \"-\";\n\t\t}\n\t}\n\tconst seconds = diff % 60;\n\tdiff = (diff - seconds) / 60;\n\tconst minutes = diff % 60;\n\tdiff = (diff - minutes) / 60;\n\tconst hours = diff;\n\tif (hours >= 48 && !showFull) {\n\t\t// >2 days\n\t\treturn getText(\"days\", Math.floor(diff / 24));\n\t}\n\tif (hours >= 24 && showFull) {\n\t\tconst hours = diff % 24;\n\t\tdiff = (diff - hours) / 24;\n\t\tconst days = diff;\n\t\treturn sprintf(\"%02d:%02d:%02d\", days, hours, minutes) + (hideSeconds ? \"\" : sprintf(\":%02d\", seconds));\n\t}\n\treturn sprintf(\"%02d:%02d\", hours, minutes) + (hideSeconds ? \"\" : sprintf(\":%02d\", seconds));\n}\n\n// Formats datetime-local input into an ISO3601 timezone-aware string\nexport function formatISO3601(timestamp: string | dayjs.Dayjs): string {\n\tconst djs = dayjs(timestamp, \"YYYY-MM-DDTHH:mm\", true);\n\tif (!djs.isValid()) {\n\t\tthrow new Error(\"Invalid timestamp\");\n\t}\n\treturn djs.format(\"YYYY-MM-DDTHH:mm:ss.SSSZ\");\n}\n\nsetInterval(() => {\n\tconst el = document.getElementById(\"footer_server_time\");\n\tif (el != null) {\n\t\tel.innerText = serverTime().format(\"HH:mm:ss\");\n\t}\n}, 500);\n", "import { h, Fragment, Component } from \"preact\";\nimport register from \"preact-custom-element\";\nimport { Reducer, useEffect, useMemo, useReducer, useState } from \"preact/hooks\";\nimport { dayjs, getGradient } from \"../util\";\nimport getText from \"../translation\";\nimport { sprintf } from \"sprintf-js\";\nimport { fromBase64 } from \"js-base64\";\nimport { answerQuestion, getAllQuestions, getUserQuestions, getAnnouncements, updateAnnouncement, deleteAnnouncement } from \"../api/contest\";\nimport { apiToast, createToast } from \"../toast\";\nimport { BigSpinner, Paginator } from \"./common\";\nimport { getCall, postCall } from \"../api/client\";\nimport { buildScoreBreakdownModal } from \"./maxscore_breakdown\";\nimport { confirm } from \"./modal\";\nimport { defaultClient } from \"../api/client\";\nimport { formatDuration, serverTime } from \"../time\";\n\nexport function ContestRemainingTime({ target_time, reload }: { target_time: dayjs.Dayjs; reload: boolean }) {\n\tlet [text, setText] = useState(formatDuration(target_time));\n\n\tfunction updateTime() {\n\t\tsetText(formatDuration(target_time));\n\t\tif (reload) {\n\t\t\tlet diff = target_time.diff(serverTime(), \"s\");\n\t\t\tif (diff < 0) {\n\t\t\t\tconsole.log(\"Reloading webpage...\");\n\t\t\t\twindow.location.reload();\n\t\t\t}\n\t\t}\n\t}\n\n\tuseEffect(() => {\n\t\tupdateTime();\n\t\tconst interval = setInterval(() => {\n\t\t\tupdateTime();\n\t\t}, 500);\n\t\treturn () => clearInterval(interval);\n\t}, []);\n\n\treturn {text};\n}\n\nexport function ContestCountdown({ target_time, type }: { target_time: string; type: string }) {\n\tlet timestamp = parseInt(target_time);\n\tif (isNaN(timestamp)) {\n\t\tconsole.error(\"unix timestamp is somehow NaN\", target_time);\n\t\treturn <>Invalid Timestamp;\n\t}\n\tconst endTime = dayjs(timestamp);\n\treturn (\n\t\t<>\n\t\t\t{endTime.diff(serverTime()) <= 0 ? (\n\t\t\t\t{{ running: getText(\"contest_ended\"), before_start: getText(\"contest_running\") }[type]}\n\t\t\t) : (\n\t\t\t\t\n\t\t\t)}\n\t\t\n\t);\n}\n\ntype LeaderboardResponse = {\n\tproblem_ordering: number[];\n\tproblem_names: Record;\n\tentries: {\n\t\tuser: UserBrief;\n\t\tscores: Record;\n\t\ttotal: number;\n\n\t\tnum_solved: number;\n\t\tpenalty: number;\n\t\tlast_time: string | null;\n\t\tfreeze_time: string | null;\n\t\tlast_times: Record;\n\t\tattempts: Record; // TODO: check if will still be null once finished\n\t}[];\n\n\tadvanced_filter: boolean;\n\n\tfreeze_time?: string;\n\ttype: \"classic\" | \"acm-icpc\";\n};\n\nexport function ContestLeaderboard({ contestID, editor }: { contestID: number; editor: boolean }) {\n\tlet [loading, setLoading] = useState(true);\n\tlet [problems, setProblems] = useState<{ id: number; name: string }[]>([]);\n\tlet [leaderboard, setLeaderboard] = useState(null);\n\tlet [lastUpdated, setLastUpdated] = useState(null);\n\n\tlet [generated, setGenerated] = useState(null);\n\n\tconst firstSolves = useMemo(() => {\n\t\tlet firstSolves: Record = {};\n\t\tif (leaderboard == null || typeof leaderboard.entries === \"undefined\") {\n\t\t\treturn {};\n\t\t}\n\t\tfor (let entry of leaderboard.entries) {\n\t\t\tfor (let times of Object.entries(entry.last_times)) {\n\t\t\t\tlet problemID = parseInt(times[0]);\n\t\t\t\tif (entry.scores[problemID] != 100) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif (typeof firstSolves[problemID] == \"undefined\" || firstSolves[problemID].minTime > times[1]) {\n\t\t\t\t\tfirstSolves[problemID] = { minTime: times[1], userID: entry.user.id };\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn firstSolves;\n\t}, [problems, leaderboard]);\n\n\tconsole.log(firstSolves);\n\n\tasync function loadLeaderboard() {\n\t\tsetLoading(true);\n\t\tconst res = await getCall(`/contest/${contestID}/leaderboard`, {\n\t\t\tgenerated_acc: generated == null ? undefined : generated,\n\t\t});\n\t\tif (res.status === \"error\") {\n\t\t\tapiToast(res);\n\t\t\treturn;\n\t\t}\n\t\tsetLastUpdated(\n\t\t\tres.data.entries.reduce((ant: string | null, prez): string | null => {\n\t\t\t\tif (prez.last_time == null) {\n\t\t\t\t\treturn ant;\n\t\t\t\t}\n\t\t\t\tif (ant == null) {\n\t\t\t\t\treturn prez.last_time;\n\t\t\t\t}\n\t\t\t\treturn dayjs(ant).isBefore(prez.last_time) ? prez.last_time : ant;\n\t\t\t}, null)\n\t\t);\n\t\tconsole.log(res.data);\n\t\tsetLeaderboard(res.data);\n\t\tsetProblems(res.data.problem_ordering.map((val) => ({ id: val, name: res.data.problem_names[val] })));\n\t\tsetLoading(false);\n\t}\n\n\tuseEffect(() => {\n\t\tloadLeaderboard().catch(console.error);\n\t}, [contestID, generated]);\n\n\tif (loading || leaderboard == null) {\n\t\treturn (\n\t\t\t<>\n\t\t\t\t\n\t\t\t\t\n\t\t\t\n\t\t);\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t\n\t\t\t{(generated != null || (leaderboard.advanced_filter && leaderboard.entries.filter((entry) => entry.user.generated).length > 0)) && (\n\t\t\t\t\n\t\t\t)}\n\t\t\t
\n\t\t\t\t

\n\t\t\t\t\t{getText(\"last_updated_at\")}: {lastUpdated ? dayjs(lastUpdated).format(\"DD/MM/YYYY HH:mm\") : \"-\"}\n\t\t\t\t

\n\t\t\t\t{leaderboard.freeze_time && serverTime().isAfter(leaderboard.freeze_time) && (\n\t\t\t\t\t

\n\t\t\t\t\t\t{getText(\"freeze_time\")}: {dayjs(leaderboard.freeze_time).format(\"DD/MM/YYYY HH:mm\")}\n\t\t\t\t\t

\n\t\t\t\t)}\n\t\t\t
\n\t\t\t\n\t\t\t\t\n\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t\t{leaderboard.type == \"acm-icpc\" && (\n\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t{problems.map((pb) => (\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t))}\n\t\t\t\t\t\t{leaderboard.type == \"classic\" && (\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t)}\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t\t{leaderboard.entries.map((entry, idx) => (\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t{leaderboard?.type == \"acm-icpc\" && (\n\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t{problems.map((pb) =>\n\t\t\t\t\t\t\t\tleaderboard?.type == \"classic\" ? (\n\t\t\t\t\t\t\t\t\t editor && buildScoreBreakdownModal(pb.id, contestID, entry.user.id)}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{pb.id in entry.scores && entry.scores[pb.id] >= 0 ? entry.scores[pb.id] : \"-\"}\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t) : entry.scores[pb.id] >= 0 ? (\n\t\t\t\t\t\t\t\t\t= 100 ? \"black\" : undefined,\n\t\t\t\t\t\t\t\t\t\t\tbackgroundColor: (() => {\n\t\t\t\t\t\t\t\t\t\t\t\tif (typeof firstSolves[pb.id] !== \"undefined\" && firstSolves[pb.id].userID == entry.user.id) {\n\t\t\t\t\t\t\t\t\t\t\t\t\treturn \"#51a300\";\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\treturn getGradient(entry.scores[pb.id] >= 100 ? 1 : 0, 1);\n\t\t\t\t\t\t\t\t\t\t\t})(),\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{entry.scores[pb.id] >= 0 ? (\n\t\t\t\t\t\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t\t{entry.scores[pb.id] >= 100 ? \"+\" : \"-\"} {entry.attempts[pb.id] > 0 && entry.attempts[pb.id]}\n\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t\t\t{entry.scores[pb.id] >= 100 && (\n\t\t\t\t\t\t\t\t\t\t\t\t\t{formatDuration(Math.floor(entry.last_times[pb.id] ?? -1) * 60, true, true)}\n\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t\t\"-\"\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t{leaderboard?.type == \"classic\" && }\n\t\t\t\t\t\t\n\t\t\t\t\t))}\n\t\t\t\t\t{leaderboard.entries.length == 0 && (\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t{/* TODO: Update here if header changes */}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t\t)}\n\t\t\t\t\n\t\t\t
\n\t\t\t\t\t\t\t{getText(\"position\")}\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t{getText(\"name\")}\n\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t{getText(\"icpc_num_solved\")}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t{getText(\"penalty\")}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t{pb.name}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t{getText(\"total\")}\n\t\t\t\t\t\t\t
{idx + 1}.\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t{entry.user.display_name.length > 0 ? `${entry.user.display_name} (${entry.user.name})` : entry.user.name}\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t{entry.num_solved}{entry.penalty}-{entry.total}
\n\t\t\t\t\t\t\t\t

{getText(\"no_users\")}

\n\t\t\t\t\t\t\t
\n\t\t\tDownload CSV\n\t\t\n\t);\n}\n\nfunction formatJSONTime(t: string, format_key: string): string {\n\treturn dayjs(t).format(getText(format_key));\n}\n\nexport function AnnouncementView({ ann, canEditAnnouncement }: { ann: Announcement; canEditAnnouncement: boolean }) {\n\tlet [text, setText] = useState(ann.text);\n\tlet [expandAnnouncement, setExpandAnnouncement] = useState(false);\n\n\tasync function editAnnouncement() {\n\t\tawait updateAnnouncement(ann, text);\n\t\tsetExpandAnnouncement(false);\n\t}\n\n\tif (expandAnnouncement) {\n\t\treturn (\n\t\t\t
\n\t\t\t\t (e.preventDefault(), setExpandAnnouncement(!expandAnnouncement))}>\n\t\t\t\t\t[{getText(\"button.cancel\")}]\n\t\t\t\t\n\t\t\t\t