PageSourceSearch

http://4x4bets.ai/g_assets/js/global.js?v=1788500837379

js 4x4bets.ai collected 2026-10-05 15:26:56 UTC 14,261 bytes, 372 lines download raw bytes

1// cache: 2026-10-05 04:14:54
2
3if (typeof moment !== 'undefined') {
4    moment.defaultFormat = "YYYY-MM-DD HH:mm:ss";
5    moment.locale('th');
6}
7if (typeof Vue !== 'undefined') {
8    Vue.filter('num', v=>intToNum(v));
9    Vue.filter('money', v=>intToMoney(v));
10    Vue.directive('select2', {
11        twoWay: true,
12        bind: function(el, binding, vnode) {
13            let attr = vnode.data.attrs;
14            Vue.nextTick(()=>{
15                $(el)
16                    .select2(attr.options)
17                    .on('select2:select', e=> {
18                        let data = e.params.data.id;
19                        vueDirectiveModel(vnode, data);
20                        _.set(vnode.model)
21                        attr.model = data;
22                    })
23                    .on('select2:unselecting', e=> {
24                        vueDirectiveModel(vnode, '');
25                    }).trigger('change')
26                ;
27            });
28        },
29        update: function(el, binding, vnode) {
30            Vue.nextTick(()=> {
31                $(el).trigger('change');
32            });
33        },
34        unbind: function(el) {
35            $(el).off().select2('destroy');
36        }
37    });
38}
39_.move = function (array, from, to) {
40    return array.splice(to, 0, array.splice(from, 1)[0]);
41};
42
43
44function intToMoney(num) { 
45    if(num === null || isNaN(num) || (!num && num != 0)) return 'รอปรับยอด' + '...';
46    return Number(num).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 })
47}
48function intToNum(num) {
49    if(num === null || isNaN(num) || (!num && num != 0)) return 'กำลังโหลด' + '...';
50    return Number(num).toLocaleString();
51}
52function swapPositive(num) {
53    return num == 0 ? num : -num;
54}
55function pad0(num, toString = true) {
56    return num<0?'00':num<10?'0'+num:(toString?num.toString():num);
57}
58
59async function post(url, data) {
60    let r = await fetch(url, {method: 'POST', headers: {'content-type': 'application/json'}, body: JSON.stringify(data)});
61    try {
62        return r.json();
63    } catch (e) {
64        return {success: false, code: e.code, data: e.message};
65    }
66}
67
68async function _get(url) {
69    let r = await fetch(url, {method: 'GET', headers: {'content-type': 'application/json'}});
70    let contentType = r.headers.get('content-type');
71    if (contentType && contentType.includes('application/json')) {
72        try {
73            return await r.json();
74        } catch (e) {
75            return {success: false, code: e.code, data: e.message};
76        }
77    } else {
78        // กรณีที่ไม่ได้รับ JSON กลับมา
79        let text = await r.text();  // รับข้อมูลเป็นข้อความ
80        // console.error('Received non-JSON response:', text);
81        // return {success: false, code: 'INVALID_JSON', data: text};
82    }
83}
84
85function sleep(ms) {
86  return new Promise(resolve => setTimeout(resolve, ms));
87}
88
89function bytesToSize(bytes) {
90    var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
91    if (bytes == 0) return '0 Byte';
92    var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
93    return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[i];
94}
95function fileToBase64(file) {
96    return new Promise((resolve) => {
97        const reader = new FileReader();
98        try {
99            reader.readAsDataURL(file);
100            reader.onload = () => resolve(reader.result);
101            reader.onerror = error => resolve(false);
102        } catch (e) {
103            resolve(false)
104        }
105    });
106}
107window.modal = {
108    info(msg, title = 'แจ้งเตือน') {
109        return Swal.fire({title, html: msg, icon: 'info', allowOutsideClick: false});
110    },
111    message(msg, title) {
112        return Swal.fire({title, html: msg, allowOutsideClick: false});
113    },
114    success(msg, title = 'สำเร็จ', opt = {}) {
115        let op = _.merge({title, html: msg, icon: 'success', allowOutsideClick: false}, opt);
116        return Swal.fire(op);
117    },
118    error(msg, title = 'ผิดพลาด') {
119        return Swal.fire({title, html: msg, icon: 'error', allowOutsideClick: false});
120    },
121    confirm(msg, title = 'ยืนยัน', option) {
122        let opt = {
123            title,
124            html: msg,
125            icon: 'warning',
126            showCancelButton: true,
127            allowOutsideClick: false,
128            reverseButtons: true // สลับตำแหน่งของปุ่ม
129        };
130
131        return new Promise(resolve => {
132            Swal.fire(_.merge(opt, option)).then(r=>{
133                resolve(r.isConfirmed ? (r.value ?? true) : false);
134            })
135        });
136
137    },
138    confirmLoading(msg, title = 'ยืนยัน', option) {
139        let opt = {
140            title,
141            html: msg,
142            icon: 'warning',
143            showCancelButton: true,
144            allowOutsideClick: false,
145            showLoaderOnConfirm: true,
146        };
147
148        return new Promise(resolve => {
149            Swal.fire(_.merge(opt, option)).then(r=>{
150                resolve(r.isConfirmed ? (r.value ?? true) : false);
151            })
152        });
153    },
154    preConfirmLoading(msg, title = 'ยืนยัน', option = {}){
155        const base = {
156            title, html: msg, icon: 'warning',
157            showCancelButton: true,
158            allowOutsideClick: () => !Swal.isLoading(),
159            showLoaderOnConfirm: true,
160            preConfirm: option.preConfirm || (async () => true)
161        };
162
163        return Swal.fire(_.merge(base, _.omit(option, ['preConfirm']))).then(r => r.isConfirmed);
164    }
165};
166function nl2br(str, is_xhtml) {
167    if (typeof str === 'undefined' || str === null) {
168        return '';
169    }
170    var breakTag = (is_xhtml || typeof is_xhtml === 'undefined') ? '<br/>' : '<br>';
171    return (str + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1' + breakTag + '$2');
172}
173window.humantime = {
174    full_th: function (datetime, with_weekday, format = false) {
175        var mm = moment(datetime, format || 'YYYY-MM-DD HH:mm:ss');
176        return mm.locale('th').format((with_weekday?'dddd ':'')+'D MMMM')+' '+(parseInt(moment(datetime, format || 'YYYY-MM-DD HH:mm:ss').locale('th').format('YYYY'))+543);
177    },
178    timeago: function (datetime, bracket, format) {
179        var mm = moment(datetime, format || 'YYYY-MM-DD HH:mm:ss');
180        return (bracket ? '(':'') +mm.fromNow() + (bracket ? ')':'');
181    },
182    time_with_ago: function (datetime, time_ago = true, format) {
183        var mm = moment(datetime, format || 'YYYY-MM-DD HH:mm:ss');
184        return mm.format('DD/MM/YYYY HH:mm:ss') + (time_ago ? ' ('+mm.fromNow()+')' : '');
185    },
186    weekday: function () {
187
188    },
189    clock: function (datetime, with_second, format) {
190        var mm = moment(datetime, format || 'YYYY-MM-DD HH:mm:ss');
191        return mm.format('HH:mm'+(with_second?':ss':''));
192    },
193    isToday: function (datetime, format) {
194        var mm = moment(datetime, format || 'YYYY-MM-DD HH:mm:ss');
195        return mm.isSame(moment(), 'day');
196    },
197    getTimeRemaining(endtime, string = true){
198        const total = Date.parse(endtime) - Date.parse(new Date());
199        const s = Math.floor( (total/1000) % 60 );
200        const m = Math.floor( (total/1000/60) % 60 );
201        const h = Math.floor( (total/(1000*60*60)) % 24 );
202        const d = Math.floor( total/(1000*60*60*24) );
203
204        return {
205            total,
206            day: d || 0,
207            hour: (h < 10 ? '0' : '') + h || 0,
208            minute: (m < 10 ? '0' : '') + m || 0,
209            second: (s < 10 ? '0' : '') + s || 0,
210        };
211    }
212};
213
214window.func = {
215    genPaginate({el = '#pagination', list } = {}, cb) {
216        $.jqPaginator(el, {
217            wrapper: '',
218            first: '<li class="first page-item"><a class="page-link" href="javascript:;">&laquo;</a></li>',
219            prev: '<li class="prev page-item"><a class="page-link" href="javascript:;">&lt;</a></li>',
220            next: '<li class="next page-item"><a class="page-link" href="javascript:;">&gt;</a></li>',
221            last: '<li class="last page-item"><a class="page-link" href="javascript:;">&raquo;</a></li>',
222            page: '<li class="page page-item"><a class="page-link" href="javascript:;">{{page}}</a></li>',
223            totalPages: +list.totalPages || Math.floor(+list.totalRecords / +list.length) || 0,
224            totalCounts: +list.totalRecords || +list.recordsTotal || 0,
225            pageSize: +list.length,
226            currentPage: +list.page,
227            visiblePages: 7,
228            onPageChange: (page, type)=> {
229                if (type !== 'change') return; //prevent loop
230                //$this.paging.page = page;
231                if (typeof cb === 'function') cb(page);
232            }
233        });
234    },
235};
236function vueDirectiveModel(vnode, setVal) {
237    let model = vnode.data.directives.find(o => o.name === 'model');
238    if (!model) return null;
239    return _.set(vnode.context, model.expression, setVal);
240}
241
242window.toast = {
243    secondary(msg, title = 'แจ้งเตือน', opt) {
244        iziToast.show(_.merge({
245            title, message: msg,
246            icon: 'fa fa-info-circle'
247        }, opt));
248    },
249    info(msg, title = 'แจ้ง', opt) {
250        iziToast.show(_.merge({
251            color: 'blue',
252            layout: 2,
253            position: 'topRight',
254            title, message: msg,
255            icon: 'fa fa-info-circle'
256        }, opt));
257    },
258    success(msg, title = 'สำเร็จ', opt) {
259        iziToast.show(_.merge({
260            color: 'green',
261            layout: 2,
262            position: 'topRight',
263            title, message: msg,
264            icon: 'fa fa-check-circle'
265        }, opt));
266    },
267    warning(msg, title = 'แจ้งเตือน', opt) {
268        iziToast.show(_.merge({
269            color: 'yellow',
270            layout: 2,
271            position: 'topRight',
272            title, message: msg,
273            icon: 'fa fa-exclamation-circle'
274        }, opt));
275    },
276    error(msg, title = 'ผิดพลาด', opt) {
277        iziToast.show(_.merge({
278            color: 'red',
279            layout: 2,
280            position: 'topRight',
281            resetOnHover: true,
282            title, message: msg,
283            icon: 'fa fa-times-circle'
284        }, opt));
285    },
286    chat(msg, title = 'แชท', opt = {}) {
287        iziToast.show(_.merge({
288            color: 'blue',
289            layout: 2,
290            // icon: 'fa fa-comment',
291            image: 'https://image.flaticon.com/icons/png/512/149/149071.png',
292            position: 'topCenter',
293            closeOnClick: true,
294            // buttons: [
295            //     ['<button>ตอบ</button>', function (instance, toast) {
296            //         alert("Hello world!");
297            //     }, true]
298            // ],
299            balloon: true,
300            resetOnHover: true,
301            title, message: msg
302        }, opt));
303    },
304    primary(msg, from, image = null, color = 'yellow', btnSets = null) {
305        iziToast.show({
306            color,
307            layout: 2,
308            // icon: 'fa fa-comment',
309            image: image || 'https://image.flaticon.com/icons/png/512/149/149071.png',
310            position: 'topRight',
311            buttons: btnSets,
312            resetOnHover: true,
313            title: from, message: msg
314        });
315    },
316};
317
318let component_option = {
319    datepicker_option: {
320        default: {
321            opens: 'left',
322            showDropdowns: true,
323            timePicker: true,
324            timePicker24Hour: true,
325            alwaysShowCalendars: true,
326            locale: {},
327            maxYear: moment(),
328            endDate: moment(),
329            ranges: {
330                'วันนี้': [moment().startOf('day'), moment().endOf('day')],
331                'เมื่อวาน': [moment().subtract(1, 'days').startOf('day'), moment().subtract(1, 'days').endOf('day')],
332                'อาทิตย์นี้ (อา.-ส.)': [moment().startOf('week'), moment().endOf('week')],
333                '7 วันล่าสุด': [moment().subtract(6, 'days').startOf('day'), moment().endOf('day')],
334                '30 วันล่าสุด': [moment().subtract(29, 'days').startOf('day'), moment().endOf('day')],
335                'เดือนนี้': [moment().startOf('month').startOf('day'), moment().endOf('month').endOf('day')],
336                'เดือนก่อน': [moment().subtract(1, 'month').startOf('month').startOf('day'), moment().subtract(1, 'month').endOf('month').endOf('day')]
337            },
338            // showCustomRangeLabel: 'กำหนดเอง',
339        },
340        single_date: {
341            singleDatePicker: true,
342            showDropdowns: true,
343            // minYear: 1901,
344            // maxYear: parseInt(moment().format('YYYY'),10),
345            locale: {
346                format: 'YYYY-MM-DD'
347            },
348            autoUpdateInput: false,
349        },
350        range_no_time: {
351            opens: 'left',
352            showDropdowns: true,
353            timePicker: false,
354            alwaysShowCalendars: true,
355            locale: {
356                format: 'YYYY-MM-DD'
357            },
358            maxYear: moment(),
359            endDate: moment(),
360            ranges: {
361                'วันนี้': [moment().startOf('day'), moment().endOf('day')],
362                'เมื่อวาน': [moment().subtract(1, 'days').startOf('day'), moment().subtract(1, 'days').endOf('day')],
363                'อาทิตย์นี้ (อา.-ส.)': [moment().startOf('week'), moment().endOf('week')],
364                '7 วันล่าสุด': [moment().subtract(6, 'days').startOf('day'), moment().endOf('day')],
365                '30 วันล่าสุด': [moment().subtract(29, 'days').startOf('day'), moment().endOf('day')],
366                'เดือนนี้': [moment().startOf('month').startOf('day'), moment().endOf('month').endOf('day')],
367                'เดือนก่อน': [moment().subtract(1, 'month').startOf('month').startOf('day'), moment().subtract(1, 'month').endOf('month').endOf('day')]
368            },
369            // showCustomRangeLabel: 'กำหนดเอง',
370        }
371    },
372};

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.