PageSourceSearch

http://my-kannada.com/assets/js/noti.js

js my-kannada.com collected 2026-10-03 01:39:37 UTC 21,291 bytes, 682 lines download raw bytes

1const errorsCache = new Map();
2
3let currentOnClose = null;
4let popupVisibleTimer = null;
5
6const ICONS = {
7    success: `
8        <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
9            <path d="M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20Zm-1.2 13.6-4-4 1.4-1.4 2.6 2.6 5.6-5.6 1.4 1.4-7 7Z" />
10        </svg>`,
11    error: `
12        <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
13            <path d="M12 2a10 10 0 1 0 0 20 10 10 0 0 0 0-20Zm3.7 12.3-1.4 1.4-2.3-2.3-2.3 2.3-1.4-1.4 2.3-2.3-2.3-2.3 1.4-1.4 2.3 2.3 2.3-2.3 1.4 1.4-2.3 2.3 2.3 2.3Z" />
14        </svg>`,
15    info: `
16        <svg viewBox="0 0 24 24" aria-hidden="true" focusable="false">
17            <path d="M11 10h2v7h-2v-7Zm0-3h2v2h-2V7Z" />
18            <path d="M12 2a10 10 0 1 0 .01 0H12Zm0 18a8 8 0 1 1 .01-16A8 8 0 0 1 12 20Z" />
19        </svg>`,
20    warning: `
21        <svg viewBox="0 0 96 96" aria-hidden="true" focusable="false">
22            <path d="M48 8 6 82h84L48 8Z" opacity=".12" />
23            <path d="M48 10 8 80h80L48 10Zm0 8 33.2 58H14.8L48 18Z" />
24            <path d="M44 36h8v22h-8V36Zm0 28h8v8h-8v-8Z" />
25        </svg>`,
26    gift: `
27        <svg viewBox="0 0 96 96" aria-hidden="true" focusable="false">
28            <path d="M16 38h64v42H16V38Z" opacity=".12" />
29            <path d="M14 34h68v16h-6v32H20V50h-6V34Zm14 16v24h16V50H28Zm24 0v24h16V50H52Zm22-8H22v4h52v-4Z" />
30            <path d="M43 34c-9.5-.2-17-4.1-17-10.3C26 18.8 30 16 34.2 16 41.7 16 46 24.4 48 30.5 50 24.4 54.3 16 61.8 16 66 16 70 18.8 70 23.7 70 29.9 62.5 33.8 53 34h-10Zm-1.6-8.1C39.3 22 37 20 34.2 20 31.7 20 30 21.5 30 23.7c0 3 4.5 5.6 12.1 6.2-.2-1.1-.5-2.5-.7-4Zm12.5 4C61.5 29.3 66 26.7 66 23.7c0-2.2-1.7-3.7-4.2-3.7-2.8 0-5.1 2-7.2 5.9-.2 1.5-.5 2.9-.7 4Z" />
31        </svg>`,
32    aml: `
33        <svg viewBox="0 0 96 96" aria-hidden="true" focusable="false">
34            <path d="M48 8 18 20v24c0 19 12.8 36.8 30 42 17.2-5.2 30-23 30-42V20L48 8Z" opacity=".12" />
35            <path d="M48 6 16 18.8V44c0 20.6 13.8 39.8 32 45.2C66.2 83.8 80 64.6 80 44V18.8L48 6Zm24 18.2V44c0 16.6-10 32.2-24 37-14-4.8-24-20.4-24-37V24.2l24-9.6 24 9.6Z" />
36            <path d="m43.6 57.2-11-11 5.6-5.6 5.4 5.4 15-15 5.6 5.6-20.6 20.6Z" />
37        </svg>`,
38    completed: `
39    <svg viewBox="0 0 96 96" aria-hidden="true" focusable="false">
40        <path d="M48 8a40 40 0 1 0 0 80 40 40 0 0 0 0-80Z" opacity=".12" />
41        <path d="M48 6a42 42 0 1 0 0 84 42 42 0 0 0 0-84Zm0 76a34 34 0 1 1 0-68 34 34 0 0 1 0 68Z" />
42        <path d="m41.5 58.5-13-13 5.7-5.7 7.3 7.3 20.3-20.3 5.7 5.7-26 26Z" />
43    </svg>`,
44
45    pending: `
46    <svg viewBox="0 0 96 96" aria-hidden="true" focusable="false">
47        <path d="M48 8a40 40 0 1 0 0 80 40 40 0 0 0 0-80Z" opacity=".12" />
48        <path d="M48 6a42 42 0 1 0 0 84 42 42 0 0 0 0-84Zm0 76a34 34 0 1 1 0-68 34 34 0 0 1 0 68Z" />
49        <path d="M44 24h8v26l18 10-4 7-22-12V24Z" />
50    </svg>`
51};
52
53function injectNotificationStyles() {
54    if (document.getElementById('modern-notification-styles')) {
55        return;
56    }
57
58    const style = document.createElement('style');
59    style.id = 'modern-notification-styles';
60    style.textContent = `
61        #v-notifications {
62            position: fixed;
63            left: 50%;
64            bottom: 24px;
65            z-index: 999999999;
66            display: grid;
67            gap: 10px;
68            width: min(440px, calc(100vw - 32px));
69            transform: translateX(-50%);
70            pointer-events: none;
71        }
72
73        #v-notifications .v-snack__wrapper {
74            display: flex;
75            align-items: center;
76            justify-content: space-between;
77            gap: 16px;
78            min-height: 52px;
79            padding: 12px 14px 12px 18px;
80            border: 1px solid rgba(255, 255, 255, .12);
81            border-radius: 16px;
82            background: rgba(17, 24, 39, .92);
83            color: #fff;
84            box-shadow: 0 18px 45px rgba(0, 0, 0, .28);
85            backdrop-filter: blur(14px);
86            pointer-events: auto;
87            animation: notiSlideIn .22s ease-out;
88        }
89
90        #v-notifications .v-snack__wrapper.is-leaving {
91            animation: notiSlideOut .18s ease-in forwards;
92        }
93
94        #v-notifications .v-snack__content {
95            font-size: 14px;
96            line-height: 1.45;
97            overflow-wrap: anywhere;
98        }
99
100        #v-notifications .v-snack__btn,
101        .dialog__close {
102            display: inline-grid;
103            place-items: center;
104            border: 0;
105            background: transparent;
106            cursor: pointer;
107        }
108
109        #v-notifications .v-snack__btn {
110            width: 34px;
111            height: 34px;
112            border-radius: 999px;
113            color: currentColor;
114            opacity: .9;
115        }
116
117        #v-notifications .v-snack__btn:hover,
118        .dialog__close:hover {
119            background: rgba(255, 255, 255, .1);
120        }
121
122        #v-notifications svg,
123        .dialog__close svg {
124            width: 22px;
125            height: 22px;
126            fill: currentColor;
127        }
128
129        .custom-popup {
130            position: fixed;
131            inset: 0;
132            z-index: 99999999999999999;
133            display: grid;
134            place-items: center;
135            padding: 20px;
136            background: rgba(15, 23, 42, .58);
137            backdrop-filter: blur(8px);
138            animation: popupFadeIn .18s ease-out;
139        }
140
141        .custom-popup-fade-out {
142            animation: popupFadeOut .18s ease-in forwards;
143        }
144
145        .custom-popup .discard-modal {
146            position: relative;
147            width: min(var(--popup-width, 500px), calc(100vw - 32px));
148            overflow: hidden;
149            border: 1px solid rgba(148, 163, 184, .22);
150            border-radius: 24px;
151            background: radial-gradient(circle at 50% 10%, rgba(250, 204, 21, .22), transparent 45%), linear-gradient(135deg, #fff7ed 0%, #eef2ff 100%);
152            color: #0f172a;
153            text-align: center;
154            box-shadow: 0 24px 70px rgba(2, 6, 23, .32);
155            transform-origin: center center;
156        }
157
158        .custom-popup .dialog__close {
159            position: absolute;
160            top: 14px;
161            right: 14px;
162            z-index: 2;
163            width: 38px;
164            height: 38px;
165            border-radius: 999px;
166            color: #334155;
167        }
168
169        .custom-popup__visual {
170            display: grid;
171            place-items: center;
172            min-height: 172px;
173            
174            color: #f59e0b;
175        }
176
177        .custom-popup__visual.is-error { color: #ef4444; }
178        .custom-popup__visual.is-gift { color: #8b5cf6; }
179        .custom-popup__visual.is-aml { color: #0f766e; }
180        .custom-popup__visual.is-info { color: #2563eb; }
181        .custom-popup__visual.is-completed { color: #16a34a; }
182        .custom-popup__visual.is-pending { color: #f59e0b; }
183
184        .custom-popup__visual svg {
185            width: 108px;
186            height: 108px;
187            fill: currentColor;
188        }
189
190        .custom-popup__body {
191            padding: 30px 32px 32px;
192        }
193
194        .custom-popup .discard-modal__title {
195            display: inline-block;
196            margin-bottom: 12px;
197            font-size: clamp(1.35rem, 3vw, 1.65rem);
198            font-weight: 700;
199            line-height: 1.2;
200        }
201
202        .custom-popup .discard-modal__text {
203            margin-bottom: 24px;
204            color: #475569;
205            font-size: 15px;
206            line-height: 1.6;
207            overflow-wrap: anywhere;
208        }
209
210        .custom-popup .discard-modal__verification-btn {
211            width: 100%;
212            min-height: 46px;
213            border: 0;
214            border-radius: 14px;
215            background: #111827;
216            color: #fff;
217            font-weight: 700;
218            cursor: pointer;
219            box-shadow: 0 12px 24px rgba(17, 24, 39, .18);
220            transition: transform .16s ease, box-shadow .16s ease, background .16s ease;
221        }
222
223        .custom-popup .discard-modal__verification-btn:hover {
224            background: #020617;
225            box-shadow: 0 16px 30px rgba(17, 24, 39, .24);
226            transform: translateY(-1px);
227        }
228
229        @keyframes notiSlideIn {
230            from { opacity: 0; transform: translateY(10px) scale(.98); }
231            to { opacity: 1; transform: translateY(0) scale(1); }
232        }
233
234        @keyframes notiSlideOut {
235            to { opacity: 0; transform: translateY(8px) scale(.98); }
236        }
237
238        @keyframes popupFadeIn {
239            from { opacity: 0; }
240            to { opacity: 1; }
241        }
242
243        @keyframes popupFadeOut {
244            to { opacity: 0; }
245        }
246
247        @media (max-width: 520px) {
248            #v-notifications {
249                bottom: 16px;
250            }
251
252            .custom-popup {
253                padding: 14px;
254            }
255
256            .custom-popup__body {
257                padding: 24px 20px 22px;
258            }
259
260            .custom-popup__visual {
261                min-height: 142px;
262            }
263
264            .custom-popup__visual svg {
265                width: 88px;
266                height: 88px;
267            }
268        }
269    `;
270    document.head.appendChild(style);
271}
272
273function htmlToFragment(html) {
274    const template = document.createElement('template');
275    template.innerHTML = String(html || '').trim();
276    return template.content.firstElementChild;
277}
278
279function getTextMessage(key, fallback = '') {
280    if (typeof getMessage === 'function') {
281        return getMessage(key);
282    }
283
284    return fallback;
285}
286
287function ensureNotificationsRoot() {
288    injectNotificationStyles();
289
290    let root = document.getElementById('v-notifications');
291
292    if (root) {
293        return root;
294    }
295
296    root = document.createElement('div');
297    root.id = 'v-notifications';
298    root.className = 'v-snack v-snack--active v-snack--bottom v-snack--has-background';
299
300    const app = document.getElementById('app') || document.body;
301    app.prepend(root);
302
303    return root;
304}
305
306function removeElementAnimated(element, className = 'is-leaving', delay = 180) {
307    if (!element || element.dataset.removing === 'true') {
308        return;
309    }
310
311    element.dataset.removing = 'true';
312    element.classList.add(className);
313
314    window.setTimeout(() => {
315        element.remove();
316    }, delay);
317}
318
319function getNotificationIcon(status) {
320    if (status === 'error') {
321        return ICONS.error;
322    }
323
324    if (status === 'info') {
325        return ICONS.info;
326    }
327
328    return ICONS.success;
329}
330
331function noti(msg, status = 'success', legacyStatus, options) {
332    if (typeof window.siteToast === 'function') {
333        return window.siteToast(msg, status, legacyStatus, options);
334    }
335
336    const notifications = ensureNotificationsRoot();
337
338    while (notifications.querySelectorAll('.v-snack__wrapper').length >= 3) {
339        notifications.querySelector('.v-snack__wrapper')?.remove();
340    }
341
342    const notification = htmlToFragment(`
343        <div class="v-snack__wrapper v-sheet theme--dark" data-status="${status}">
344            <div role="status" aria-live="polite" class="v-snack__content">${msg || ''}</div>
345            <div class="v-snack__action">
346                <button type="button" class="v-btn v-btn--text theme--dark v-size--default white--text v-snack__btn" aria-label="Close notification">
347                    <span class="v-btn__content">${getNotificationIcon(status)}</span>
348                </button>
349            </div>
350        </div>
351    `);
352
353    notification.querySelector('.v-snack__btn').addEventListener('click', () => closeNoti(notification));
354    notifications.append(notification);
355
356    window.setTimeout(() => closeNoti(notification), 2500);
357}
358
359function closeNoti(el) {
360    const notification = el?.closest ? el.closest('.v-snack__wrapper') : el;
361    removeElementAnimated(notification);
362}
363
364function isAuthorized() {
365    const input = document.getElementById('user-authorized');
366    return Boolean(input && input.value !== 'false');
367}
368
369function requireAuthorized() {
370    if (isAuthorized()) {
371        return true;
372    }
373
374    location.replace('../signin');
375    return false;
376}
377
378function removeCurrentPopup() {
379    document.getElementById('custom-popup')?.remove();
380}
381
382function getPopupIconType({ img, status, type }
382 = {}) {
383    const source = String(img || type || status || '').toLowerCase();
384
385    if (source.includes('completed')) {
386        return 'completed';
387    }
388
389    if (source.includes('pending')) {
390        return 'pending';
391    }
392
393    if (source.includes('gift')) {
394        return 'gift';
395    }
396
397    if (source.includes('aml')) {
398        return 'aml';
399    }
400
401    if (source.includes('error') || status === 'error') {
402        return 'error';
403    }
404
405    if (source.includes('info') || status === 'info') {
406        return 'info';
407    }
408
409    return 'warning';
410}
411
412function getPopupWidth(img) {
413    const source = String(img || '').toLowerCase();
414    return source.includes('qrcode.svg') || source.includes('antiphishing.svg') ? 400 : 500;
415}
416
417function createPopup({
418                         title,
419                         message,
420                         img,
421                         status,
422                         type,
423                         withBtn = false,
424                         btnMessage,
425                         buttonAction,
426                         onClose
427                     }) {
428    injectNotificationStyles();
429    removeCurrentPopup();
430
431    currentOnClose = typeof onClose === 'function' ? onClose : null;
432
433    const iconType = getPopupIconType({ img, status, type });
434
435    const popup = htmlToFragment(`
436        <div id="custom-popup" role="dialog" aria-modal="true" class="custom-popup v-dialog__content v-dialog__content--active" showed="false">
437            <div tabindex="0" class="discard-modal v-dialog dialog v-dialog--active" style="--popup-width: ${getPopupWidth(img)}px;">
438                <button type="button" class="dialog__close" aria-label="Close popup">
439                    ${ICONS.error}
440                </button>
441                <div class="custom-popup__visual is-${iconType}">
442                    ${ICONS[iconType] || ICONS.warning}
443                </div>
444                <div class="custom-popup__body">
445                    <div class="discard-modal__title discard-title">${title || ''}</div>
446                    <div class="discard-modal__text">${message || ''}</div>
447                    ${withBtn ? `
448                        <button type="button" class="discard-modal__verification-btn v-btn v-btn--is-elevated v-btn--has-bg theme--light v-size--default">
449                            <span class="v-btn__content">${btnMessage || getTextMessage('popup.button.good', 'OK')}</span>
450                        </button>` : ''}
451                </div>
452            </div>
453        </div>
454    `);
455
456    popup.querySelector('.dialog__close').addEventListener('click', closePopup);
457
458    const button = popup.querySelector('.discard-modal__verification-btn');
459
460    if (button) {
461        button.addEventListener('click', () => {
462            if (typeof buttonAction === 'function') {
463                buttonAction();
464                return;
465            }
466
467            closePopup();
468        });
469    }
470
471    const target = document.querySelector('footer') || document.body;
472    target.after(popup);
473
474    clearTimeout(popupVisibleTimer);
475    popupVisibleTimer = window.setTimeout(() => {
476        document.getElementById('custom-popup')?.setAttribute('showed', 'true');
477    }, 300);
478}
479
480function popup(title, message, img, status, withBtn, onClose, btnMessage) {
481    createPopup({
482        title,
483        message,
484        img,
485        status,
486        withBtn,
487        onClose,
488        btnMessage
489    });
490}
491
492async function profileRequest(payload, dataType = 'json') {
493    const response = await fetch('../api/user/profile', {
494        method: 'POST',
495        headers: {
496            'Content-Type': 'application/json; charset=UTF-8'
497        },
498        body: JSON.stringify(payload)
499    });
500
501    if (!response.ok) {
502        throw new Error(`Profile request failed: ${response.status}`);
503    }
504
505    if (dataType === 'text') {
506        return response.text();
507    }
508
509    return response.json().catch(() => null);
510}
511
512async function addErrorAction(type) {
513    try {
514        await profileRequest({
515            action: 'ADD_ACTION',
516            action_type: 'GET_ERROR',
517            type
518        });
519    } catch (ignored) {}
520}
521
522async function getErrorMessage(type) {
523    if (errorsCache.has(type)) {
524        return errorsCache.get(type);
525    }
526
527    const response = await profileRequest({
528        action: 'GET_ERROR_MESSAGE',
529        type
530    }, 'text');
531
532    errorsCache.set(type, response);
533    return response;
534}
535
536async function showErrorPopup({
537                                  type,
538                                  title,
539                                  buttonText,
540                                  buttonAction,
541                                  iconType = 'error',
542                                  onClose = null
543                              }) {
544    if (!requireAuthorized()) {
545        return;
546    }
547
548    try {
549        const message = await getErrorMessage(type);
550
551        await addErrorAction(type);
552
553        createPopup({
554            title,
555            message,
556            type: iconType,
557            withBtn: true,
558            btnMessage: buttonText,
559            buttonAction,
560            onClose
561        });
562    } catch (error) {
563        noti(getTextMessage('popup.error.load', 'Something went wrong. Please try again.'), 'error');
564    }
565}
566
567function verificationPopup(event) {
568    event?.preventDefault();
569
570    showErrorPopup({
571        type: 'OTHER',
572        title: getTextMessage('popup.title.verification'),
573        buttonText: getTextMessage('popup.button.verification'),
574        buttonAction: () => {
575            window.location.href = '../profile/settings#verification';
576        },
577        iconType: 'error'
578    });
579}
580
581function errorPopup(type, onClose, event) {
582    event?.preventDefault();
583
584    showErrorPopup({
585        type,
586        title: getTextMessage('popup.title.verification'),
587        buttonText: getTextMessage('popup.button.good'),
588        buttonAction: closePopup,
589        iconType: 'error',
590        onClose
591    });
592}
593
594function withdrawPopup(type, event) {
595    event?.preventDefault();
596
597    showErrorPopup({
598        type,
599        title: getTextMessage(type === 'WITHDRAW_AML' ? 'popup.aml.title' : 'popup.withdraw.title'),
600        buttonText: getTextMessage('popup.button.deposit.verification'),
601        buttonAction: () => {
602            location.replace('../profile/deposit-verification');
603        },
604        iconType: type === 'WITHDRAW_AML' ? 'aml' : 'error'
605    });
606}
607
608function withdrawStatusPopup(response, onClose) {
609    if (response !== 'completed' && response !== 'pending') {
610        return false;
611    }
612
613    createPopup({
614        title: getTextMessage(`withdraw.${response}.title`),
615        message: getTextMessage(`withdraw.${response}.description`),
616        type: response,
617        withBtn: true,
618        btnMessage: getTextMessage('popup.button.good', 'OK'),
619        buttonAction: closePopup,
620        onClose
621    });
622
623    return true;
624}
625
626function closePopup() {
627    const popup = document.getElementById('custom-popup');
628
629    if (!popup || popup.dataset.removing === 'true') {
630        return;
631    }
632
633    popup.dataset.removing = 'true';
634    popup.setAttribute('showed', 'false');
635    popup.classList.add('custom-popup-fade-out');
636
637    window.setTimeout(() => {
638        popup.remove();
639
640        if (typeof currentOnClose === 'function') {
641            currentOnClose();
642            currentOnClose = null;
643        }
644    }, 180);
645}
646
647function handlePopupOutsideClick(event) {
648    const popup = document.getElementById('custom-popup');
649
650    if (!popup || popup.getAttribute('showed') !== 'true') {
651        return;
652    }
653
654    const dialog = popup.querySelector('.discard-modal');
655
656    if (dialog && !dialog.contains(event.target)) {
657        closePopup();
658    }
659}
660
661function handlePopupEscape(event) {
662    if (event.key === 'Escape') {
663        closePopup();
664    }
665}
666
667document.addEventListener('click', handlePopupOutsideClick);
668document.addEventListener('keydown', handlePopupEscape);
669
670window.noti = noti;
671window.closeNoti = closeNoti;
672window.popup = popup;
673window.addErrorAction = addErrorAction;
674window.verificationPopup = verificationPopup;
675window.errorPopup = errorPopup;
676window.withdrawPopup = withdrawPopup;
677window.withdrawStatusPopup = withdrawStatusPopup;
678window.closePopup = closePopup;
679
680if (typeof window.siteToast !== 'function') {
681    ensureNotificationsRoot();
682}

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.