1import {Modal} from '../ui/modal.js' 2import {firemsg} from '../ui/firemsg.js' 3import {Compatible} from '../vendor/compatible.js' 4import {globalProgress, L} from '../ui/utils.js' 5import {Cookie} from '../ui/cookie.js' 6 7const error = {error: 'ÐеизвеÑÑÐ½Ð°Ñ Ð¾Ñибка'} 8 9const __fp = async (le) => { 10 const set = val => { 11 const _cs = ['\x66\x70', '\x67\x6d', '\x2e\x78', '\x76'] 12 const els = document.querySelectorAll(_cs[2] + _cs[1] + _cs[0] + _cs[3]) 13 els.forEach(el => el.value = val) 14 } 15 if(le) { 16 set('') 17 return 18 } 19 set('i') 20 set('t') 21 const u = await Compatible.load() 22 set('l') 23 const r = await u.get() 24 set('r') 25 const h = r.components 26 const l = document.createElement('\x63\x61\x6e\x76\x61\x73') 27 const lc = l && l.getContext('\x77\x65\x62\x67\x6c') 28 const ld = lc && lc.getExtension('\x57\x45\x42\x47\x4c\x5f\x64\x65\x62\x75\x67\x5f\x72\x65\x6e\x64\x65\x72\x65\x72\x5f\x69\x6e\x66\x6f') 29 h.gpu = {value: lc && ld && lc.getParameter(ld['\x55\x4e\x4d\x41\x53\x4b\x45\x44\x5f\x52\x45\x4e\x44\x45\x52\x45\x52\x5f\x57\x45\x42\x47\x4c']) || null} 30 l.remove() 31 set(btoa(JSON.stringify(h, null, ' '))) 32} 33 34/** @type string */ 35let _fpvError 36 37const _dblclickDebugHandler = () => { 38 const element = document.createElement('a') 39 const text = _fpvError || document.querySelector('.xgmfpv').value 40 element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text)) 41 element.setAttribute('download', 'xgm-debug.txt') 42 43 element.style.display = 'none' 44 document.body.appendChild(element) 45 46 element.click() 47 48 document.body.removeChild(element) 49} 50 51/** 52 * @param {HTMLButtonElement} button 53 * @returns {Promise<void>} 54 */ 55const _fp = async button => { 56 _fpvError = undefined 57 button.disabled = true 58 try { 59 await __fp() 60 } catch (e) { 61 _fpvError = e.toString() 62 } 63 button.disabled = false 64} 65 66/** @type {HTMLFormElement} */ 67const loginForm = document.getElementById('login-form') 68if (loginForm) { 69 const debugLabel = loginForm.querySelector('[for="login-password"]') 70 debugLabel && debugLabel.addEventListener('dblclick', _dblclickDebugHandler) 71 72 const submit = loginForm.querySelector('[type=submit]') 73 submit.disabled = true 74 75 document.body.addEventListener('ui.modal-open', e => { 76 if (e.detail.name !== 'login') return 77 _fp(submit) 78 Modal.open(async () => { 79 // noinspection JSUnresolvedVariable 80 if(e.target.dataset && e.target.dataset.loginPresetUsername) { 81 loginForm.elements.username.value = e.target.dataset.loginPresetUsername 82 loginForm.elements.password.focus() 83 } else { 84 loginForm.elements.username.focus() 85 } 86 return loginForm 87 }) 88 }) 89 90 loginForm.addEventListener('submit', async e => { 91 e.preventDefault() 92 93 const formData = new FormData() 94 formData.set('do', 'login') 95 formData.set('ajax', '1') 96 // noinspection JSUnresolvedVariable 97 formData.set('username', loginForm.elements.username.value) 98 // noinspection JSUnresolvedVariable 99 formData.set('password', loginForm.elements.password.value) 100 formData.set('fromRoute', location.pathname) 101 102 const request = await fetch('/authentication/login', {method: 'post', body: formData}) 103 const response = await request.json().catch(() => error) 104 if (response === 'OK') { 105 loginForm.submit() 106 Modal.close() 107 globalProgress(false) 108 return 109 } 110 firemsg(`ÐÑибка! ${response.error}`) 111 }) 112} 113 114/** @type {HTMLFormElement} */ 115const registerForm = document.getElementById('register-form') 116if (registerForm) { 117 const debugLabel = registerForm.querySelector('[for="registration-password"]') 118 debugLabel && debugLabel.addEventListener('dblclick', _dblclickDebugHandler) 119 const pleaseWaitEl = registerForm.querySelector(".please-wait") 120 const submitTick = /** @type {HTMLElement} */ registerForm.querySelector('.please-wait-tick') 121 const submitIcon = /** @type {HTMLElement} */ registerForm.querySelector('.please-wait-icon') 122 123 const submit = registerForm.querySelector('[type=submit]') 124 125 const acceptLegal = registerForm.querySelector('.registration-accept-legal') 126 let forceDisable = true 127 const refreshRegisterButton = () => { 128 /** @type {HTMLButtonElement|null} */ 129 let registerButton = registerForm.querySelector('.register-button') 130 if (acceptLegal.checked && !forceDisable) { 131 registerButton.disabled = false 132 registerButton.classList.add('btn-primary') 133 registerButton.classList.remove('disabled') 134 } else { 135 registerButton.disabled = true 136 registerButton.classList.remove('btn-primary') 137 registerButton.classList.add('disabled') 138 } 139 } 140 acceptLegal.addEventListener('change', refreshRegisterButton) 141 142 // noinspection JSUnresolvedVariable 143 /** @type HTMLInputElement */ 144 const username = registerForm.elements.username 145 146 document.body.addEventListener('ui.modal-open', e => { 147 if (e.detail.name !== 'register') return 148 149 let it = 30 150 let t = it 151 let i = null 152 __fp(0x364111) 153 154 pleaseWaitEl.style.display = 'block' 155 submitIcon.style.setProperty('--fa-animation-duration', (t / 20) + 's') 156 i = setInterval(() => { 157 if (t <= 1) { 158 clearInterval(i) 159 pleaseWaitEl.style.display = 'none' 160 forceDisable = false 161 _fp(submit) 162 refreshRegisterButton() 163 return 164 } 165 t-- 166 submitTick.innerHTML = t.toString() 167 submitIcon.classList.add('fa-spin', 'fa-spin-reverse') 168 if (t % 5 === 0) { 169 submitIcon.style.setProperty('--fa-animation-duration', (t / 20) + 's') 170 } 171 refreshRegisterButton() 172 }, 1000) 173 174 Modal.open(async () => { 175 username.focus() 176 return registerForm 177 }) 178 }) 179 180 username.addEventListener('focusout', async e => { 181 /** @type {HTMLElement} */ 182 const div = e.target.nextElementSibling 183 184 if (username.value.length < 4) { 185 div.innerHTML = '<span class="text-error">' + L('ÐÐ¼Ñ Ð¿Ð¾Ð»ÑзоваÑÐµÐ»Ñ Ð´Ð¾Ð»Ð¶Ð½Ð¾ бÑÑÑ Ð´Ð»Ð¸Ð½Ð½ÐµÐµ', 'The username must be longer', 'ç¨æ·åå¿ é¡»æ´é¿') + '</span>' 186 return 187 } 188 189 const formData = new FormData() 190 formData.set('username', username.value) 191 192 const request = await fetch('/registration/check-identity', {method: 'post', body: formData}) 193 const response = await request.json().catch(() => error) 194 195 if (response.error) { 196 firemsg(response.error) 197 return 198 } 199 200 if (response === 1) { 201 div.innerHTML = '<span class="text-success">' + L('ÐÑо Ð¸Ð¼Ñ Ð´Ð¾ÑÑÑпно', 'This username is available', 'æ¤ç¨æ·åå¯ç¨') + '</span>' 202 return 203 } 204 205 div.innerHTML = '<span class="text-warning">' + L('ÐÑо Ð¸Ð¼Ñ Ð½ÐµÐ´Ð¾ÑÑÑпно', 'This username is not available', 'æ¤ç¨æ·åä¸å¯ç¨') + '</span>' 206 }) 207 208 // noinspection JSUnresolvedVariable 209 /** @type HTMLInputElement */ 210 const email = registerForm.elements.email 211 email.addEventListener('input', e => { 212 /** @type {HTMLElement} */ 213 const div = e.target.nextElementSibling 214 const reg = /^[._A-Za-z\d-]+@[.a-z\d-]+(\.[a-z]{2,4})$/ 215 if (!reg.exec(email.value)) { 216 div.innerHTML = '<span class="text-error">' + L('ÐевеÑнÑй ÑоÑмаÑ', 'Wrong format', 'æ ¼å¼é误') + '</span>' 217 return 218 } 219 div.innerHTML = '<span class="text-success">' + L('ÐÐ', 'OK', '好ç') + '</span>' 220 }) 221 222 223 // noinspection JSUnresolvedVariable 224 /** @type HTMLInputElement */ 225 const password = registerForm.elements.password 226 const passwordDiv = password.nextElementSibling 227 228 // noinspection JSUnresolvedVariable 229 /** @type HTMLInputElement */ 230 const confirmpassword = registerForm.elements.confirmpassword 231 const confirmpasswordDiv = confirmpassword.nextElementSibling 232 233 /** @param e Event */ 234 const passwordHandler = e => { 235 if (e.target === password) { 236 passwordDiv.innerHTML = password.value.length < 8 237 ? '<span class="text-warning">' + L('СлабÑй паÑолÑ', 'Weak password', 'å¯ç 强度ä½') + '</span>' 238 : '<span class="text-success">' + L('ÐоÑмалÑнÑй паÑолÑ', 'The password is ok', 'å¯ç 没é®é¢') + '</span>' 239 } 240 241 confirmpasswordDiv.innerHTML = password.value === confirmpassword.value 242 ? '<span class="text-success">' + L('ÐаÑоли ÑовпадаÑÑ', 'Passwords match', 'å¯ç å¹é ') + '</span>' 243 : '<span class="text-error">' + L('ÐаÑоли не ÑовпадаÑÑ', 'Passwords do not match', 'å¯ç ä¸å¹é ') + '</span>' 244 } 245 246 password.addEventListener('input', passwordHandler) 247 confirmpassword.addEventListener('input', passwordHandler) 248} 249 250if (document.querySelector('.integration-vk-auth')) setTimeout(__fp, 260) 251 252/** 253 * @event CustomEvent#security.authentication 254 * @event CustomEvent#security.registration 255 * @event CustomEvent#security.logout 256 * @event CustomEvent#security.change-identity 257 * @event CustomEvent#security.change-credentials 258 * @event CustomEvent#security.reset-credentials 259 */ 260const securityAction = Cookie.getItem('securityAction') 261if(securityAction) { 262 const securitySource = Cookie.getItem('securitySource') 263 Cookie.removeItem('securityAction') 264 Cookie.removeItem('securitySource') 265 266 setTimeout(() => { // wait for the subscribers in the same thread 267 if(securityAction == 'authentication') { 268 document.body.dispatchEvent(new CustomEvent("security.authentication", { bubbles: true, detail: { source: securitySource } })) 269 } else if(securityAction == 'registration') { 270 document.body.dispatchEvent(new CustomEvent("security.registration", { bubbles: true, detail: { source: securitySource } })) 271 } else if(securityAction == 'logout') { 272 document.body.dispatchEvent(new CustomEvent("security.logout", { bubbles: true, detail: { 273 source: securitySource, 274 identity: Cookie.getItem('securityIdentity'), 275 id: Cookie.getItem('securityId') 276 } })) 277 Cookie.removeItem('securityIdentity') 278 Cookie.removeItem('securityId') 279 } else if(securityAction == 'change-identity') { 280 document.body.dispatchEvent(new CustomEvent("security.change-identity", { bubbles: true, detail: { source: securitySource } })) 281 } else if(securityAction == 'change-credentials') { 282 document.body.dispatchEvent(new CustomEvent("security.change-credentials", { bubbles: true, detail: { source: securitySource } })) 283 } else if(securityAction == 'reset-credentials') { 284 document.body.dispatchEvent(new CustomEvent("security.reset-credentials", { bubbles: true, detail: { source: securitySource } })) 285 } 286 }, 0) 287}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.