Hệ thống pháp luật

ỦY BAN NHÂN DÂN
THÀNH PHỐ HÀ NỘI
-------

CỘNG HÒA XÃ HỘI CHỦ NGHĨA VIỆT NAM
Độc lập - Tự do - Hạnh phúc
---------------

Số: 256/KH-UBND

Hà Nội, ngày 24 tháng 10 năm 2023

 

KẾ HOẠCH

KIỂM TRA VIỆC TRIỂN KHAI THỰC HIỆN QUY ĐỊNH CỦA PHÁP LUẬT TRONG CÁC LĨNH VỰC CÓ LIÊN QUAN ĐẾN CÔNG TÁC PCCC VÀ CNCH TRÊN ĐỊA BÀN THÀNH PHỐ

Thực hiện Công điện số 796/CĐ-TTg ngày 13/9/2023, công điện 825/CĐ-TTg ngày 15/9/2023 của Thủ tướng Chính phủ về tăng cường công tác phòng cháy, chữa cháy; để kịp thời phát hiện, chấn chỉnh, khắc phục những tồn tại, thiếu sót, nâng cao hiệu quả công tác quản lý nhà nước trong các lĩnh vực có liên quan đến công tác PCCC và CNCH, UBND Thành phố ban hành Kế hoạch kiểm tra việc triển khai thực hiện quy định của pháp luật trong các lĩnh vực có liên quan công tác PCCC và CNCH trên địa bàn Thành phố, cụ thể như sau:

I. MỤC ĐÍCH, YÊU CẦU

1. Siết chặt kỷ luật, kỷ cương; nâng cao vai trò trách nhiệm trong lãnh đạo, chỉ đạo của người đứng đầu các cấp ủy Đảng, chính quyền địa phương, các ngành chức năng. Đánh giá đúng thực trạng việc thực hiện và công tác phối hợp trong quản lý nhà nước (QLNN) của các cơ quan quản lý; ý thức, nhận thức, trách nhiệm của người đứng đầu cơ sở, chủ hộ gia đình và người dân trong việc thực hiện quy định pháp luật của các lĩnh vực có liên quan đến công tác PCCC và CNCH.

2. Kiểm tra việc triển khai thực hiện quy định của pháp luật trong các lĩnh vực có liên quan công tác PCCC và CNCH tại một số đơn vị cấp huyện, cấp xã và tại cơ sở thuộc loại hình tập trung đông người, trọng điểm có nguy cơ cháy, nổ cao (chung cư, nhà ở nhiều căn hộ, cơ sở kinh doanh dịch vụ cho thuê trọ, nhà ở kết hợp kinh doanh, sản xuất...) trên địa bàn Thành phố.

3. Qua công tác kiểm tra, kịp thời phát hiện những tồn tại, hạn chế, yếu kém để xử lý nghiêm đối với các tập thể, cá nhân vi phạm, thiếu trách nhiệm trong thực hiện nhiệm vụ được giao; tổng hợp khó khăn, vướng mắc, bất cập trong quá trình triển khai thực hiện để kịp thời có các biện pháp, giải pháp sát hợp, căn cơ; kiến nghị đề xuất cấp có thẩm quyền các vấn đề bất cập, nhằm nâng cao hiệu lực, hiệu quả công tác QLNN trong các lĩnh vực liên quan đến PCCC và CNCH trong thời gian tới.

4. Việc kiểm tra phải đảm bảo tính khách quan, toàn diện, đánh giá đúng thực trạng tình hình, trách nhiệm của các tập thể, cơ sở, cá nhân trong thực hiện quy định của pháp luật liên quan đến công tác PCCC&CNCH; xử lý nghiêm tất cả hành vi vi phạm theo quy định của pháp luật. Quá trình kiểm tra không làm ảnh hưởng đến hoạt động của đơn vị, cơ sở được kiểm tra.

II. ĐỐI TƯỢNG, THỜI GIAN, HÌNH THỨC KIỂM TRA

1. Đối tượng kiểm tra: UBND cấp huyện, cấp xã; Công an cấp huyện, cấp xã; cơ sở tập trung đông người, cơ sở trọng điểm có nguy cơ cháy, nổ cao (chung cư, nhà ở nhiều căn hộ, cơ sở kinh doanh dịch vụ cho thuê trọ, nhà ở kết hợp kinh doanh, sản xuất,...) trên địa bàn Thành phố (do đồng chí Trưởng đoàn kiểm tra xem xét, quyết định).

2. Thời gian, địa điểm kiểm tra

2.1. Thời gian: Từ ngày 25/10/2023 đến ngày 15/12/2023.

2.2. Địa điểm: Làm việc trực tiếp tại đơn vị, cơ sở được lựa chọn kiểm tra.

3. Hình thức kiểm tra: Kiểm tra đột xuất theo kế hoạch.

III. NỘI DUNG KIỂM TRA

1. Kiểm tra việc quán triệt, chỉ đạo, tổ chức triển khai thực hiện Nghị Quyết, Chỉ thị, Kế hoạch, văn bản chỉ đạo của Thành ủy, HĐND Thành phố, UBND Thành phố đã ban hành trong thời gian vừa qua (2. Kiểm tra công tác quản lý nhà nước, công tác xử lý vi phạm (nếu có) của các cơ quan được giao nhiệm vụ quản lý; việc chấp hành quy định pháp luật về đất đai, quy hoạch, đầu tư, xây dựng, an toàn điện, an toàn về PCCC và CNCH đối với một số cơ sở thuộc loại hình chung cư, nhà ở nhiều căn hộ, cơ sở kinh doanh dịch vụ cho thuê trọ, nhà ở kết hợp kinh doanh, sản xuất... trên địa bàn Thành phố.

3. Trường hợp phát hiện cơ sở có vi phạm quy định các lĩnh vực được kiểm tra, giao UBND cấp huyện chỉ đạo xử lý theo quy định; đồng thời đánh giá, làm rõ trách nhiệm công tác quản lý nhà nước của các cơ quan, tập thể, cá nhân có liên quan, đề xuất hình thức xử lý theo quy định.

IV. THÀNH PHẦN ĐOÀN KIỂM TRA

1. Đại diện lãnh đạo UBND Thành phố - Trưởng đoàn;

2. Đồng chí Đại tá Dương Đức Hải, Phó Giám đốc Công an Thành phố - Phó Trưởng đoàn Thường trực;

3. Đại diện lãnh đạo Văn phòng UBND Thành phố - Phó Trưởng đoàn;

4. Đại diện lãnh đạo và chuyên viên các Sở, ngành: Công Thương, Xây dựng, Quy hoạch - Kiến trúc, Tài nguyên và Môi trường, Tổng Công ty Điện lực thành phố Hà Nội - Thành viên;

5. Đại diện Lãnh đạo, cán bộ các phòng nghiệp vụ thuộc Công an Thành phố - Thành viên;

6. Đại diện lãnh đạo UBND cấp huyện nơi có cơ sở được lựa chọn kiểm tra - Thành viên;

7. Công an Thành phố cử 01 đồng chí làm Thư ký đoàn kiểm tra;

8. Mời cơ quan báo, đài Thành phố phối hợp tham gia đưa tin, bài trên các phương tiện thông tin truyền thông: Đài Truyền hình Hà Nội, Báo Hà Nội mới, Báo Kinh tế đô thị, Báo An ninh thủ đô...

(Trong trường hợp đồng chí Trưởng đoàn bận công tác, giao đồng chí Phó Trưởng đoàn Thường trực chịu trách nhiệm duy trì việc kiểm tra của Đoàn)

V. PHƯƠNG PHÁP KIỂM TRA

1. Đối với UBND các cấp

- Kiểm tra việc quán triệt, lãnh đạo, chỉ đạo tổ chức triển khai thực hiện các văn bản của Thành ủy, HĐND Thành phố, UBND Thành phố.

- Kết quả thực hiện theo chức năng, nhiệm vụ được phân công trong công tác QLNN về các lĩnh vực đất đai, quy hoạch, đầu tư, xây dựng, an toàn điện, an toàn về PCCC và CNCH.

- Kiểm tra đối chiếu với báo cáo, hồ sơ, tài liệu của các đơn vị, từ đó tổng hợp, đánh giá kết quả việc triển khai thực hiện theo chức năng nhiệm vụ được phân công, đồng thời hướng dẫn giải pháp khắc phục các tồn tại, vướng mắc.

2. Đối với Công an các cấp

- Kiểm tra công tác tham mưu cấp ủy chính quyền địa phương; việc quán triệt, chỉ đạo triển khai, thực hiện công tác QLNN về PCCC và CNCH theo phân công, phân cấp.

- Kiểm tra đối chiếu với báo cáo, hồ sơ, tài liệu của các đơn vị, từ đó tổng hợp, đánh giá kết quả việc triển khai thực hiện theo chức năng nhiệm vụ được phân công, đồng thời hướng dẫn giải pháp khắc phục các tồn tại, vướng mắc.

3. Đối với Công ty điện lực thành viên cấp huyện, Hợp tác xã kinh doanh điện

- Kiểm tra việc thực hiện chỉ đạo của Thành phố, Sở Công Thương, Tổng Công ty điện lực thành phố Hà Nội trong lĩnh vực điện, việc kiểm tra an toàn sử dụng điện sau công tơ, xử lý các vi phạm trong sử dụng điện đối với các hộ gia đình, cơ sở trên địa bàn thuộc phạm vi quản lý.

- Kiểm tra đối chiếu với báo cáo, hồ sơ, tài liệu của các đơn vị, từ đó tổng hợp, đánh giá kết quả việc triển khai thực hiện theo chức năng nhiệm vụ được phân, đồng thời hướng dẫn giải pháp khắc phục các tồn tại, vướng mắc.

4. Đối với cơ sở: Kiểm tra trực tiếp tại cơ sở việc chấp hành các quy định của pháp luật trong lĩnh vực đất đai, quy hoạch, đầu tư, xây dựng, an toàn điện, an toàn về PCCC và CNCH của cơ sở; các điều kiện an toàn thực tế liên quan đến lĩnh vực điện, PCCC và CNCH

VI. PHÂN CÔNG NHIỆM VỤ

1. Công an Thành phố

- Chủ trì, tham mưu Chủ tịch UBND Thành phố thành lập Đoàn kiểm tra liên ngành cấp Thành phố.

- Chủ trì, phối hợp với các Sở, ngành: Công thương, Xây dựng, Quy hoạch - Kiến trúc, Tài nguyên và Môi trường, Tổng Công ty Điện lực thành phố Hà Nội xây dựng đề cương chi tiết phục vụ kiểm tra. Đề xuất đồng chí Trưởng đoàn phân công nội dung, nhiệm vụ cụ thể cho các đơn vị, thành viên Đoàn kiểm tra.

- Nghiên cứu, đề xuất đơn vị, cơ sở được kiểm tra, thời gian kiểm tra; chuẩn bị các điều kiện phục vụ công tác kiểm tra; thông báo lịch kiểm tra tới các thành viên Đoàn Kiểm tra.

- Thực hiện kiểm tra các nội dung liên quan đến công tác QLNN về PCCC và CNCH; việc thực hiện các quy định của pháp luật, các điều kiện an toàn PCCC và CNCH thực tế tại cơ sở...

- Chủ trì việc triển khai thực hiện Kế hoạch kiểm tra; tổng hợp, xây dựng Báo cáo về kết quả kiểm tra; tham mưu UBND Thành phố kịp thời chỉ đạo, giải quyết những tồn tại, hạn chế, khó khăn, vướng mắc, bất cập khi kiểm tra.

2. Văn phòng UBND Thành phố

- Phối hợp với Công an Thành phố tham mưu UBND Thành phố thành lập Đoàn kiểm tra liên ngành cấp Thành phố; nghiên cứu, đề xuất đồng chí Trưởng đoàn kiểm tra về đối tượng kiểm tra, thời gian kiểm tra, phân công nhiệm vụ cụ thể cho các đơn vị, thành viên Đoàn kiểm tra; chuẩn bị các điều kiện phục vụ công tác kiểm tra; đôn đốc, hướng dẫn các đơn vị triển khai thực hiện Kế hoạch kiểm tra...

- Phối hợp với Công an Thành phố thông báo lịch kiểm tra tới các thành viên Đoàn Kiểm tra.

3. Các Sở, ngành: Công Thương, Xây dựng, Quy hoạch - Kiến trúc, Tài nguyên và Môi trường, Kế hoạch và đầu tư, Tổng Công ty Điện lực thành phố Hà Nội

- Căn cứ chức năng, nhiệm vụ, lĩnh vực được phân công quản lý, phụ trách, xây dựng đề cương kiểm tra chi tiết thuộc các lĩnh vực đất đai, quy hoạch, đầu tư, xây dựng, an toàn điện, gửi về CATP (qua Phòng Cảnh sát PCCC và CNCH, số 2 Dương Đình Nghệ, Cầu Giấy, Hà Nội) trước ngày 27/10/2023 để tổng hợp xây dựng đề cương chung.

- Tổ chức kiểm tra theo chức năng, nhiệm vụ được phân công việc thực hiện các quy định của pháp luật trong lĩnh vực đất đai, quy hoạch, đầu tư, xây dựng, an toàn điện đối với các đơn vị, cơ sở được kiểm tra.

4. UBND các quận, huyện, thị xã và các cơ sở được kiểm tra

- Phân công các đơn vị, bộ phận chức năng có liên quan tham gia và chuẩn bị các điều kiện thực tế phục vụ Đoàn kiểm tra; xây dựng báo cáo, cung cấp thông tin, tài liệu thực hiện chức năng quản lý nhà nước, hồ sơ tài liệu thể hiện việc chấp hành các quy định của pháp luật trong các lĩnh vực đất đai, quy hoạch, đầu tư, xây dựng, an toàn điện, an toàn về PCCC và CNCH theo yêu cầu của Đoàn Kiểm tra.

- Tổ chức thực hiện các chỉ đạo, kiến nghị của Đoàn Kiểm tra, báo cáo kết quả thực hiện về UBND Thành phố theo quy định.

VII. TỔ CHỨC THỰC HIỆN

1. Căn cứ chức năng, nhiệm vụ được phân công, các đơn vị tổ chức triển khai thực hiện nghiêm túc nội dung của Kế hoạch.

2. Giao các Sở, ngành: Công an Thành phố, Công Thương, Xây dựng, Quy hoạch - Kiến trúc, Tài nguyên và Môi trường, Kế hoạch và Đầu tư, Tổng Công ty Điện lực thành phố Hà Nội:

(1) Phân công lãnh đạo, cán bộ tham gia Đoàn kiểm tra theo đúng thành phần tại Kế hoạch; gửi danh sách lãnh đạo, cán bộ tham gia Đoàn kiểm tra về UBND Thành phố (qua Công an Thành phố - Phòng Cảnh sát PCCC và CNCH) theo biểu mẫu gửi kèm Kế hoạch trước ngày 25/10/2023 để tập hợp.

(2) Chuẩn bị các tài liệu có liên quan phục vụ công tác kiểm tra theo quy định. Trong quá trình kiểm tra phải đánh giá sâu, cụ thể các ưu điểm, tồn tại, hạn chế của đơn vị, cơ sở; từ đó có đánh giá trách nhiệm cụ thể của các tập thể, cá nhân có liên quan trong công tác chỉ huy, chỉ đạo điều hành và tổ chức triển khai thực hiện; kiến nghị, đề xuất các giải pháp, biện pháp khắc phục.

3. Giao Công an Thành phố chủ trì, phối hợp các Sở, ngành: Công Thương, Xây dựng, Quy hoạch - Kiến trúc, Tài nguyên và Môi trường, Kế hoạch và Đầu tư, Tổng Công ty Điện lực thành phố Hà Nội tổ chức kiểm tra theo chức năng, nhiệm vụ được phân công và xây dựng báo cáo, báo cáo UBND Thành phố kết quả kiểm tra theo quy định./.

 


Nơi nhận:
- Bộ Công an (V01, C07);
- Thường trực Thành ủy;
- Thường trực HĐND Thành phố;
- Chủ tịch UBND Thành phố;
- PCT TTUBND Thành phố;
- Ủy ban MTTQVN Thành phố;
- Các Sở, ban, ngành Thành phố;
- UBND các quận, huyện, thị xã;
- VPUB: CVP, PCVP C.N.Trang, NC, KGVX,
KT, ĐT, TH;
- Lưu: VT.

TM. ỦY BAN NHÂN DÂN
KT. CHỦ TỊCH
PHÓ CHỦ TỊCH




Lê Hồng Sơn

 

...........
...................

CỘNG HÒA XÃ HỘI CHỦ NGHĨA VIỆT NAM
Độc lập - Tự do - Hạnh phúc
---------------

 

Hà Nội, ngày   tháng   năm 2023

 

BIỂU MẪU DANH SÁCH

Cử thành viên tham gia Đoàn kiểm tra liên ngành kiểm tra việc thực hiện công tác phòng cháy, chữa cháy và cứu nạn, cứu hộ trên địa bàn Thành phố Hà Nội

TT

Họ và tên

Chức vụ, Đơn vị

SĐT liên hệ

Địa chỉ Email

Ghi chú

1

 

 

 

 

 

...

 

 

 

 

 

 

 

THỦ TRƯỞNG ĐƠN VỊ

 

 



lồng nhau (bên trong) hay không const memberID = 0; const vbID = '8b9e40f0ab1530bac79aef492d9d4e2d'; // State management cho phân tích let isAnalyzing = false; // Có đang phân tích không let currentAnalyzingAddress = null; // Address đang được phân tích let currentAnalyzingElement = null; // Element đang được phân tích let currentAnalyzingBadge = null; // Badge của element đang phân tích let isPanelOpen = false; // Panel phân tích có đang mở không console.log('Tiện ích loaded - memberID:', memberID, 'vbID:', vbID); function isInViewportAndTabNoiDung(element) { const rect = element.getBoundingClientRect(); const buffer = 1500; // Buffer to preload content below the viewport (approx. 50+ lines) const viewHeight = window.innerHeight || document.documentElement.clientHeight; const isInViewport = rect.top < viewHeight + buffer && rect.bottom >= 0; const isInTabNoiDung = $(element).closest('#tab_noi_dung_vb').length > 0; return isInViewport && isInTabNoiDung; } function getAddress(element) { const validTags = ['trichyeu', 'cancu', 'phan', 'chuong', 'muc', 'tieumuc', 'dieu', 'khoan', 'diem']; const $parent = $(element).closest(validTags.join(',')); if (!$parent.length) { return null; } let addr = $parent.attr('address'); if (!addr && $parent.prop('tagName').toLowerCase() === 'trichyeu') { addr = 'trichyeu'; $parent.attr('address', addr); } return addr || null; } function processTnplClasses($element) { const tnplKeysInLine = new Set(); // key = slug hoặc text (thường là slug) $element.find('tnpl').each(function () { const $tnpl = $(this); const tnplSlug = ($tnpl.attr('slug') || '').trim().toLowerCase(); const tnplKey = tnplSlug || $tnpl.text().trim().toLowerCase(); // Đã xử lý trong cùng dòng => bỏ if (tnplKeysInLine.has(tnplKey)) { return; } tnplKeysInLine.add(tnplKey); let tnplExists = false; // Chỉ duyệt các tnpl đã được tô màu (class on) $('tnpl.on').each(function () { const $existingTnpl = $(this); const existingSlug = ($existingTnpl.attr('slug') || '').trim().toLowerCase(); const existingKey = existingSlug || $existingTnpl.text().trim().toLowerCase(); if ( existingKey === tnplKey && isInViewportAndTabNoiDung($existingTnpl[0]) ) { tnplExists = true; return false; // break each } }); if (!tnplExists) { $tnpl.addClass('on'); } }); } function processQueue() { while (pendingRequests < maxConcurrentRequests && requestQueue.length > 0) { const task = requestQueue.shift(); pendingRequests++; task() .always(() => { pendingRequests--; processQueue(); }); } } function processVisibleParagraphs() { try { $('#tab_noi_dung_vb p:not([is-posted="1"])').each(function () { let $element = $(this); if (isInViewportAndTabNoiDung(this)) { $element.attr('is-posted', '1'); $element.addClass('loading-content'); let p_innerHTML = $element.html(); let address = null; if (cac_cau_hinh.loai_noi_dung.includes('docs')) { address = getAddress($element); } const isSubP = $element.parents('p').length > 0; if (isSubP && !allow_sub_p) { $element.removeClass('loading-content'); return; // Không gửi nếu không cho phép } const postData = { p_content: p_innerHTML, cac_cau_hinh, address }; if (isSubP && allow_sub_p) { postData.sub_p = 1; } requestQueue.push(() => $.ajax({ url: '//tnpl' + (Math.floor(Math.random() * 10) + 1) + '.hethongphapluat.com/tien-ich/tim.tien.ich.php', type: 'POST', data: postData, success: function(response) { $element.html(response); processTnplClasses($element); // Đợi CTTD và các tiện ích load xong rồi mới attach badge if (memberID === 4 && typeof attachPhanTichBadge === 'function') { setTimeout(function() { // $element chính là thẻ p, kiểm tra và attach badge trực tiếp const $parent = $element.closest('phan, chuong, muc, tieumuc, dieu, khoan, diem'); if ($parent.length > 0 && $parent.find('.badge-phan-tich[data-for="' + $parent.attr('address') + '"]').length === 0) { const address = $parent.attr('address'); $element.attr('data-address', address); // Lấy tên loại thẻ cho tooltip const parentType = getParentTypeName($parent.prop('tagName').toLowerCase()); // Append badge VÀO PARENT (dieu, khoan,...) thay vì vào

để tránh xung đột CTTD const $badge = $('Phân tích'); $parent.append($badge); // Thêm class để CSS set position: relative CHỈ cho element có badge $parent.addClass('has-phan-tich-badge'); } // Xử lý các p con (nếu có sub-p) attachPhanTichBadge($element); }, 300); // Đợi 300ms để CTTD render xong } }, complete: function() { $element.removeClass('loading-content'); } }) ); processQueue(); } }); } catch(e) { console.error('Lỗi processVisibleParagraphs:', e); } } $(window).on('scroll resize', function () { processVisibleParagraphs(); }); console.log('Bắt đầu processVisibleParagraphs lần đầu...'); processVisibleParagraphs(); console.log('processVisibleParagraphs lần đầu hoàn thành'); // Chức năng phân tích điều luật (chỉ cho member_id = 4) if (memberID === 4) { // Modal cảnh báo function showWarningModal(message) { // Tạo modal nếu chưa có if ($('#warningModal').length === 0) { const modalHTML = `

`; $('body').append(modalHTML); } $('#warningModalBody').html('

' + message + '

'); $('#warningModal').modal('show'); } // Hàm lấy tên tiếng Việt của thẻ function getParentTypeName(tagName) { const typeNames = { 'phan': 'Phần', 'chuong': 'Chương', 'muc': 'Mục', 'tieumuc': 'Tiểu mục', 'dieu': 'Điều', 'khoan': 'Khoản', 'diem': 'Điểm' }; return typeNames[tagName] || 'Nội dung'; } function attachPhanTichBadge($container) { const validTags = 'phan, chuong, muc, tieumuc, dieu, khoan, diem'; $container.find('p').each(function() { const $p = $(this); const $parent = $p.closest(validTags); if ($parent.length > 0) { const address = $parent.attr('address'); // Kiểm tra đã có badge cho parent này chưa if ($parent.find('.badge-phan-tich[data-for="' + address + '"]').length === 0) { // Lưu address vào data attribute $p.attr('data-address', address); // Lấy tên loại thẻ cho tooltip const parentType = getParentTypeName($parent.prop('tagName').toLowerCase()); // Append badge vào PARENT, không vào

const $badge = $('Phân tích'); $parent.append($badge); // Thêm class để CSS set position: relative CHỈ cho element có badge $parent.addClass('has-phan-tich-badge'); } } }); } // Helper: Escape HTML entities function escapeHtml(text) { const map = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''' }; return String(text).replace(/[&<>"']/g, function(m) { return map[m]; }); } // Helper: Convert Markdown to HTML (đơn giản) function markdownToHtml(markdown) { if (!markdown) return ''; let html = markdown; // Headers html = html.replace(/^### (.*$)/gim, '

$1
'); html = html.replace(/^## (.*$)/gim, '

$1

'); html = html.replace(/^# (.*$)/gim, '

$1

'); // Bold html = html.replace(/\*\*(.*?)\*\*/g, '$1'); // Italic html = html.replace(/\*(.*?)\*/g, '$1'); // Blockquote html = html.replace(/^> (.*$)/gim, '
$1
'); html = html.replace(/^> (.*$)/gim, '
$1
'); // Lists (unordered) html = html.replace(/^\- (.*$)/gim, '
  • $1
  • '); html = html.replace(/(
  • .*<\/li>)/s, '
      $1
    '); // Lists (ordered) html = html.replace(/^\d+\. (.*$)/gim, '
  • $1
  • '); // Line breaks và paragraphs html = html.split('\n\n').map(para => { para = para.trim(); if (para.startsWith('')) { return para; } if (para) { return '

    ' + para.replace(/\n/g, '
    ') + '

    '; } return ''; }).join('\n'); // Clean up multiple line breaks html = html.replace(/\n{3,}/g, '\n\n'); return html; } // Panel fixed position function closePhanTichPanel() { const $panel = $('#phanTichPanel'); if ($panel.length) { $panel.removeClass('show'); setTimeout(() => { $panel.remove(); }, 300); } // Reset highlight và badge khi đóng panel if (currentAnalyzingElement) { currentAnalyzingElement.removeClass('highlight-border-persistent'); } if (currentAnalyzingBadge) { currentAnalyzingBadge.text('Phân tích').removeClass('analyzing'); currentAnalyzingBadge.data('analyzing', false); currentAnalyzingBadge.data('hovering', false); currentAnalyzingBadge.css({display: 'none'}); // Ẩn badge khi đóng } // Reset tất cả các element khác (trong trường hợp có nhiều) $('#tab_noi_dung_vb .highlight-border-persistent').removeClass('highlight-border-persistent'); $('#tab_noi_dung_vb .badge-phan-tich-container.analyzing').each(function() { $(this).text('Phân tích').removeClass('analyzing').data('analyzing', false); }); // Check: có CTTD pointer đang mở không? const $visiblePointers = $('.pointer:visible'); const hadCTTDOpen = $visiblePointers.length > 0; if (hadCTTDOpen) { // CÓ CTTD đang mở → giữ rightdocinfo ẩn console.log('ℹ️ CTTD pointer is visible, keeping rightdocinfo hidden'); } else { // KHÔNG có CTTD → SHOW lại rightdocinfo const $rightdocinfo = $('#rightdocinfo'); if ($rightdocinfo.length > 0) { $rightdocinfo.show(); console.log('✅ Showing rightdocinfo back (no CTTD pointer)'); } } // Reset state isAnalyzing = false; currentAnalyzingAddress = null; currentAnalyzingElement = null; currentAnalyzingBadge = null; isPanelOpen = false; // Đánh dấu panel đã đóng console.log('✅ Panel closed, state reset, isPanelOpen = false'); } // Panel đã song song với rightdocinfo → không cần MutationObserver nữa console.log('✅ Panel running in standalone mode (parallel to rightdocinfo)'); // Resize event để update panel dimensions khi browser resize let resizeTimer; $(window).on('resize', function() { clearTimeout(resizeTimer); resizeTimer = setTimeout(function() { if (isPanelOpen && $('#phanTichPanel').length > 0) { updatePanelDimensions(); console.log('✅ Panel dimensions updated on window resize'); } }, 250); // Debounce 250ms }); // Function để detect và áp dụng dimensions từ rightdocinfo function updatePanelDimensions() { const $panel = $('#phanTichPanel'); const $rightdocinfo = $('#rightdocinfo'); const $docRightCol = $('#doc-right-col'); if ($panel.length === 0) return; // Ưu tiên: doc-right-col > rightdocinfo let $reference = $docRightCol.length > 0 ? $docRightCol : $rightdocinfo; // Nếu reference bị ẩn (display:none), tạm show để get dimensions let wasHidden = false; if ($reference.length > 0 && !$reference.is(':visible')) { wasHidden = true; $reference.css('visibility', 'hidden').show(); } if ($reference.length > 0) { const refWidth = $reference.outerWidth(); const refOffset = $reference.offset(); if (refWidth && refOffset) { // Tính vị trí right từ edge màn hình const windowWidth = $(window).width(); const rightPosition = windowWidth - (refOffset.left + refWidth); $panel.css({ 'width': refWidth + 'px', 'right': rightPosition + 'px' }); console.log('✅ Panel dimensions updated:', { width: refWidth + 'px', right: rightPosition + 'px', reference: $reference.attr('id') }); } else { console.warn('⚠️ Could not get dimensions from reference element'); } // Restore trạng thái hidden nếu cần if (wasHidden) { $reference.hide().css('visibility', ''); } } else { console.warn('⚠️ No reference element found for panel dimensions'); } } function openPhanTichPanel(address, vbID) { console.log('openPhanTichPanel called with address:', address); console.log('Current state - isAnalyzing:', isAnalyzing, 'currentAnalyzingAddress:', currentAnalyzingAddress); // Kiểm tra nếu đang phân tích element khác if (isAnalyzing && currentAnalyzingAddress && currentAnalyzingAddress !== address) { const currentName = getElementDisplayName(currentAnalyzingAddress); console.warn('Already analyzing:', currentAnalyzingAddress, 'Cannot analyze:', address); showWarningModal('Vui lòng chờ phân tích ' + currentName + ' hoàn tất...'); return; } // Nếu đang phân tích cùng element → không làm gì if (isAnalyzing && currentAnalyzingAddress === address) { console.log('Already analyzing this element, ignoring duplicate request'); return; } // Panel sẽ fixed position append vào body const $rightdocinfo = $('#rightdocinfo'); // KHÔNG ẨN CTTD pointer - cho phép CTTD và panel cùng tồn tại console.log('Panel opening, CTTD pointer can stay visible'); // ẨN rightdocinfo để tiết kiệm không gian if ($rightdocinfo.length > 0) { $rightdocinfo.hide(); console.log('Hidden rightdocinfo to save space'); } // XÓA highlight persistent của TẤT CẢ elements cũ trước $('#tab_noi_dung_vb .highlight-border-persistent').removeClass('highlight-border-persistent'); console.log('Removed all previous highlight-border-persistent'); // Tìm element đang được phân tích và badge của nó const $element = $('[address="' + address + '"]'); const $badge = $element.find('.badge-phan-tich-container[data-for="' + address + '"]').first(); // Set state isAnalyzing = true; currentAnalyzingAddress = address; currentAnalyzingElement = $element; currentAnalyzingBadge = $badge; console.log('State set:', { isAnalyzing: isAnalyzing, currentAnalyzingAddress: currentAnalyzingAddress, elementFound: $element.length > 0, badgeFound: $badge.length > 0 }); // Thêm highlight persistent cho element MỚI này $element.addClass('highlight-border-persistent'); // Thay đổi badge thành "Đang phân tích..." và giữ hiển thị if ($badge.length > 0) { $badge.text('Đang phân tích...').addClass('analyzing'); // Giữ badge hiển thị và ở đúng vị trí $badge.data('analyzing', true); $badge.data('hovering', true); // Prevent auto-hide console.log('Badge set to analyzing state'); // Đảm bảo badge hiển thị ở đúng vị trí (vì dùng position: fixed) showPhanTichBadgeForParent($element); } // Tạo panel nếu chưa có - fixed position append vào body if ($('#phanTichPanel').length === 0) { const panelHTML = `
    Phân tích điều luật
    Đang phân tích...

    Đang phân tích...

    `; // Append vào body (fixed position không cần container cụ thể) $('body').append(panelHTML); // Detect width từ rightdocinfo và áp dụng cho panel updatePanelDimensions(); // Trigger show và set flag setTimeout(() => { $('#phanTichPanel').addClass('show'); isPanelOpen = true; console.log('✅ Panel opened (fixed position), isPanelOpen = true'); }, 10); } else { $('#phanTichPanelBody').html(`
    Đang phân tích...

    Đang phân tích...

    `); // Update dimensions khi re-open updatePanelDimensions(); $('#phanTichPanel').addClass('show'); isPanelOpen = true; console.log('✅ Panel re-opened (fixed position), isPanelOpen = true'); } // Bind nút đóng và ESC $(document).off('click.closePhanTich').on('click.closePhanTich', '.close-phan-tich', function() { closePhanTichPanel(); }); $(document).off('keyup.closePhanTich').on('keyup.closePhanTich', function(e) { if (e.key === 'Escape') closePhanTichPanel(); }); // Bind nút refresh - phân tích lại $(document).off('click.refreshPhanTich').on('click.refreshPhanTich', '.btn-refresh-phan-tich', function(e) { e.preventDefault(); e.stopPropagation(); const $btn = $(this); const $icon = $btn.find('i'); // Disable button và thêm animation $btn.prop('disabled', true); $icon.addClass('fa-spin'); console.log('🔄 Refresh: Phân tích lại address:', address); // Show loading trong panel $('#phanTichPanelBody').html(`
    Đang phân tích lại...

    Đang xóa cache và phân tích lại...

    `); // Gọi API xóa cache trước deletePhanTichCache(address, vbID, function(deleteSuccess) { if (deleteSuccess) { console.log('✅ Cache deleted, now re-analyzing...'); // Sau khi xóa cache, gọi lại API phân tích callPhanTichAPI(address, vbID, function() { // Enable lại button $btn.prop('disabled', false); $icon.removeClass('fa-spin'); }); } else { console.error('❌ Failed to delete cache'); $('#phanTichPanelBody').html(` `); $btn.prop('disabled', false); $icon.removeClass('fa-spin'); } }); }); // Gọi API phân tích (dùng function helper) callPhanTichAPI(address, vbID); } // Helper: Gọi API phân tích (tách riêng để dùng lại) function callPhanTichAPI(address, vbID, callback) { const randomServer = Math.floor(Math.random() * 10) + 1; $.ajax({ url: '//tnpl' + randomServer + '.hethongphapluat.com/tien-ich/phan.tich.dieu.luat.php', type: 'POST', contentType: 'application/json', timeout: 300000, // 5 phút data: JSON.stringify({ address: address, vb_id: vbID }), success: function(response) { console.log('Analysis complete for:', address, response); // Reset badge về trạng thái bình thường (nhưng vẫn hiển thị) if (currentAnalyzingBadge) { currentAnalyzingBadge.text('Phân tích').removeClass('analyzing'); currentAnalyzingBadge.data('analyzing', false); console.log('Badge reset to normal state'); } // Reset state analyzing để có thể phân tích element khác isAnalyzing = false; console.log('State reset: isAnalyzing = false, can analyze other elements now'); if (response.ok) { // Render kết quả phân tích let html = ''; html += '
    '; html += '
    ' + escapeHtml(response.ten_van_ban) + '
    '; if (response.so_hieu) { html += 'Số hiệu: ' + escapeHtml(response.so_hieu) + '
    '; } html += 'Điều khoản: ' + escapeHtml(response.address) + ''; if (response.from_cache) { html += ' Cache'; } html += '
    '; html += '
    ' + markdownToHtml(response.phan_tich) + '
    '; if (response.usage) { html += '
    '; html += 'Thống kê: '; html += 'Input tokens: ' + (response.usage.promptTokenCount || 0) + ', '; html += 'Output tokens: ' + (response.usage.candidatesTokenCount || 0); html += '
    '; } $('#phanTichPanelBody').html(html); } else { $('#phanTichPanelBody').html(` `); } if (callback) callback(); }, error: function(xhr, status, error) { console.error('Analysis error:', error); // Reset badge về trạng thái bình thường if (currentAnalyzingBadge) { currentAnalyzingBadge.text('Phân tích').removeClass('analyzing'); currentAnalyzingBadge.data('analyzing', false); } // Reset state analyzing isAnalyzing = false; let errorMsg = error; if (xhr.responseJSON && xhr.responseJSON.error) { errorMsg = xhr.responseJSON.error; } $('#phanTichPanelBody').html(` `); if (callback) callback(); } }); } // Helper: Xóa cache phân tích function deletePhanTichCache(address, vbID, callback) { const randomServer = Math.floor(Math.random() * 10) + 1; $.ajax({ url: '//tnpl' + randomServer + '.hethongphapluat.com/tien-ich/delete.phan.tich.cache.php', type: 'POST', contentType: 'application/json', timeout: 10000, data: JSON.stringify({ address: address, vb_id: vbID }), success: function(response) { console.log('Delete cache response:', response); if (callback) callback(response.ok || false); }, error: function(xhr, status, error) { console.error('Delete cache error:', error); if (callback) callback(false); } }); } // Helper: Lấy tên hiển thị của element từ address function getElementDisplayName(address) { if (!address) return 'nội dung'; const $element = $('[address="' + address + '"]'); if ($element.length === 0) return address; // Parse address: vd "dieu_3_khoan_29" -> "Khoản 29 Điều 3" // Address format: lớn đến nhỏ (phan > chuong > muc > dieu > khoan > diem) const parts = address.split('_'); const displayParts = []; for (let i = 0; i < parts.length; i += 2) { if (i + 1 < parts.length) { const type = getParentTypeName(parts[i]); const num = parts[i + 1]; displayParts.push(type + ' ' + num); } } // Reverse để hiển thị từ nhỏ đến lớn: "Khoản 29 Điều 3" (thay vì "Điều 3 Khoản 29") return displayParts.reverse().join(' '); } function openPhanTichModal(address, vbID) { // Tạo modal nếu chưa có if ($('#modalPhanTich').length === 0) { const modalHTML = ` `; $('body').append(modalHTML); } // Reset và hiển thị modal với loading $('#modalPhanTichBody').html(`
    Đang phân tích...

    Đang phân tích...

    `); $('#modalPhanTich').modal('show'); // AJAX request const randomServer = Math.floor(Math.random() * 10) + 1; $.ajax({ url: '//tnpl' + randomServer + '.hethongphapluat.com/tien-ich/phan.tich.dieu.luat.php', type: 'POST', contentType: 'application/json', data: JSON.stringify({ address: address, vb_id: vbID }), success: function(response) { if (response.ok) { // Render kết quả phân tích let html = ''; // Header thông tin văn bản html += '
    '; html += '
    ' + escapeHtml(response.ten_van_ban) + '
    '; if (response.so_hieu) { html += 'Số hiệu: ' + escapeHtml(response.so_hieu) + '
    '; } html += 'Điều khoản: ' + escapeHtml(response.address) + ''; html += '
    '; // Nội dung phân tích (Markdown -> HTML) html += '
    '; html += markdownToHtml(response.phan_tich); html += '
    '; // Thông tin usage (nếu có) if (response.usage) { html += '
    '; html += 'Thống kê: '; html += 'Input tokens: ' + (response.usage.promptTokenCount || 0) + ', '; html += 'Output tokens: ' + (response.usage.candidatesTokenCount || 0); html += '
    '; } $('#modalPhanTichBody').html(html); } else { $('#modalPhanTichBody').html(` `); } }, error: function(xhr, status, error) { let errorMsg = error; if (xhr.responseJSON && xhr.responseJSON.error) { errorMsg = xhr.responseJSON.error; } $('#modalPhanTichBody').html(` `); } }); } // Helpers: show/hide badge cho parent element (dieu, khoan,...) với position: fixed function showPhanTichBadgeForParent($parent) { // Lấy badge CỦA CHÍNH parent này (match data-for với address của parent) const parentAddress = $parent.attr('address'); const $badge = $parent.find('.badge-phan-tich-container[data-for="' + parentAddress + '"]').first(); if ($badge.length === 0) { console.warn('No badge found for parent:', parentAddress); return; } // Ẩn TẤT CẢ các badge khác để tránh overlap $('.badge-phan-tich-container').not($badge).each(function() { const $otherBadge = $(this); // Chỉ ẩn badge KHÔNG đang analyzing if (!$otherBadge.data('analyzing')) { $otherBadge.css({display: 'none'}); } }); // Show badge tạm để tính width $badge.css({display: 'inline-block', opacity: 0, visibility: 'hidden'}); const badgeWidth = $badge.outerWidth(); // Tính toán vị trí fixed dựa trên offset của parent const offset = $parent.offset(); const scrollTop = $(window).scrollTop(); const scrollLeft = $(window).scrollLeft(); // Position badge top-right của parent và show $badge.css({ display: 'inline-block', visibility: 'visible', opacity: 1, top: (offset.top - scrollTop) + 'px', left: (offset.left + $parent.outerWidth() - badgeWidth - scrollLeft - 5) + 'px' // -5px padding }); console.log('Showing badge for:', parentAddress, 'at position:', $badge.css('top'), $badge.css('left')); $parent.addClass('highlight-border'); } function hidePhanTichBadgeForParent($parent) { const $badge = $parent.find('.badge-phan-tich-container').first(); if ($badge.length === 0) return; $badge.css({display: 'none', opacity: 0}); $parent.removeClass('highlight-border'); } // Biến lưu element đang hover let currentHoveredElement = null; let hoverDebounceTimer = null; // Dùng mousemove để track chính xác element nào đang được hover $(document).on('mousemove', '#tab_noi_dung_vb', function(e) { // Tìm element gần nhất (phan, chuong, muc, dieu, khoan, diem) tại vị trí chuột const $target = $(e.target).closest('phan, chuong, muc, tieumuc, dieu, khoan, diem'); if ($target.length === 0) { // Không hover vào element nào return; } const address = $target.attr('address'); // Nếu đang hover vào cùng element → skip if (currentHoveredElement && currentHoveredElement[0] === $target[0]) { return; } // Clear debounce timer cũ if (hoverDebounceTimer) { clearTimeout(hoverDebounceTimer); } // Debounce để tránh trigger quá nhiều hoverDebounceTimer = setTimeout(function() { // Element thay đổi console.log('Hover changed to:', address); // Set flag hovering cho element mới $target.data('hovering', true); // Cancel timeout nếu có const timeoutId = $target.data('hideTimeout'); if (timeoutId) { clearTimeout(timeoutId); } // Ẩn badge của TẤT CẢ elements khác $('#tab_noi_dung_vb phan, #tab_noi_dung_vb chuong, #tab_noi_dung_vb muc, #tab_noi_dung_vb tieumuc, #tab_noi_dung_vb dieu, #tab_noi_dung_vb khoan, #tab_noi_dung_vb diem') .not($target) .each(function() { const $el = $(this); // Chỉ xóa highlight-border, KHÔNG xóa highlight-border-persistent $el.removeClass('highlight-border'); // Ẩn badge nếu KHÔNG đang analyzing const $badge = $el.find('.badge-phan-tich-container'); if ($badge.length && !$badge.data('analyzing')) { $badge.css({display: 'none'}); } }); // Attach badge nếu chưa có if (address && $target.find('.badge-phan-tich-container[data-for="' + address + '"]').length === 0) { const parentType = getParentTypeName($target.prop('tagName').toLowerCase()); const $badge = $('Phân tích'); console.log('Creating badge for address:', address, 'parentType:', parentType); $target.append($badge); $target.addClass('has-phan-tich-badge'); } // Show badge cho element này if ($target.find('.badge-phan-tich-container').length > 0) { showPhanTichBadgeForParent($target); } // Update current hovered element currentHoveredElement = $target; }, 50); // Debounce 50ms }); // Event delegation cho hover ra khỏi #tab_noi_dung_vb $(document).on('mouseleave', '#tab_noi_dung_vb', function(e) { // Clear current hovered element currentHoveredElement = null; // Ẩn tất cả badge không đang analyzing sau một khoảng thời gian setTimeout(function() { if (currentHoveredElement === null) { // Chỉ ẩn nếu thực sự không hover vào element nào $('#tab_noi_dung_vb phan, #tab_noi_dung_vb chuong, #tab_noi_dung_vb muc, #tab_noi_dung_vb tieumuc, #tab_noi_dung_vb dieu, #tab_noi_dung_vb khoan, #tab_noi_dung_vb diem') .each(function() { const $el = $(this); const $badge = $el.find('.badge-phan-tich-container'); if ($badge.length && !$badge.data('analyzing')) { $badge.css({display: 'none'}); } }); console.log('Mouse left tab_noi_dung_vb, hiding all badges'); } }, 300); }); // Event delegation cho hover ra khỏi parent (giữ lại cho badge behavior) $(document).on('mouseleave', '#tab_noi_dung_vb phan, #tab_noi_dung_vb chuong, #tab_noi_dung_vb muc, #tab_noi_dung_vb tieumuc, #tab_noi_dung_vb dieu, #tab_noi_dung_vb khoan, #tab_noi_dung_vb diem', function(e) { const $parent = $(this); const parentAddress = $parent.attr('address'); const $badge = $parent.find('.badge-phan-tich-container[data-for="' + parentAddress + '"]').first(); // Set flag parent not hovering $parent.data('hovering', false); // Nếu badge đang analyzing thì KHÔNG ẩn, GIỮ hiển thị if ($badge.length > 0 && $badge.data('analyzing')) { console.log('Badge is analyzing, keep visible'); return; } // Delay để có thời gian di chuột vào badge const timeoutId = setTimeout(() => { // Chỉ ẩn nếu cả parent và badge đều không hover và không analyzing if ($badge.length > 0 && !$parent.data('hovering') && !$badge.data('hovering') && !$badge.data('analyzing')) { hidePhanTichBadgeForParent($parent); } }, 300); // Tăng lên 300ms $parent.data('hideTimeout', timeoutId); }); // Hover vào badge → giữ hiển thị $(document).on('mouseenter', '.badge-phan-tich-container', function(e) { e.stopPropagation(); const $badge = $(this); const $parent = $badge.parent(); $badge.data('hovering', true); // Cancel timeout của parent const timeoutId = $parent.data('hideTimeout'); if (timeoutId) { clearTimeout(timeoutId); } }); // Hover ra khỏi badge → ẩn nếu không hover parent $(document).on('mouseleave', '.badge-phan-tich-container', function(e) { const $badge = $(this); $badge.data('hovering', false); const $parent = $badge.parent(); // Nếu badge đang analyzing thì KHÔNG ẩn, GIỮ hiển thị if ($badge.data('analyzing') || $badge.hasClass('analyzing')) { console.log('Badge is analyzing on mouseleave, keep visible'); return; } setTimeout(() => { // Chỉ ẩn nếu cả parent và badge đều không hover và không analyzing if (!$parent.data('hovering') && !$badge.data('hovering') && !$badge.data('analyzing') && !$badge.hasClass('analyzing')) { hidePhanTichBadgeForParent($parent); } }, 300); }); // Event delegation cho hover vào badge → hiện tooltip $(document).on('mouseenter', '.badge-phan-tich, .badge-phan-tich-container, .badge-phan-tich-fixed', function() { const $badge = $(this); const parentType = $badge.attr('data-parent-type') || 'Nội dung'; if ($badge.find('.badge-tooltip').length === 0) { const $tooltip = $('Phân tích chi tiết nội dung ' + parentType + ' này'); $badge.append($tooltip); setTimeout(() => $tooltip.addClass('show'), 10); } }); // Event delegation cho hover ra khỏi badge → ẩn tooltip $(document).on('mouseleave', '.badge-phan-tich, .badge-phan-tich-container, .badge-phan-tich-fixed', function() { const $tooltip = $(this).find('.badge-tooltip'); if ($tooltip.length > 0) { $tooltip.removeClass('show'); setTimeout(() => $tooltip.remove(), 300); } }); // Event delegation cho click badge → mở panel $(document).on('click', '.badge-phan-tich, .badge-phan-tich-container, .badge-phan-tich-fixed', function(e) { e.preventDefault(); e.stopPropagation(); const $badge = $(this); console.log('Badge clicked! Element:', $badge[0]); console.log('Badge parent:', $badge.parent().prop('tagName'), $badge.parent().attr('address')); console.log('Badge data-for:', $badge.attr('data-for')); console.log('Badge data-parent-type:', $badge.attr('data-parent-type')); // Nếu badge đang analyzing thì không cho click if ($badge.hasClass('analyzing') || $badge.data('analyzing')) { console.log('Badge is analyzing, click ignored'); return; } // Lấy address từ data-for attribute const address = $badge.attr('data-for'); console.log('Will analyze address:', address, 'vbID:', vbID); if (address && vbID) { openPhanTichPanel(address, vbID); } else { console.error('Missing address or vbID', {address, vbID}); showWarningModal('Không tìm thấy địa chỉ điều luật hoặc ID văn bản!'); } }); // Ẩn badge khi click vào CTTD $(document).on('click', 'cttd.chuthichtudong span, dctk span, dctd span', function(e) { console.log('CTTD clicked'); // Ẩn TẤT CẢ badge KHÔNG đang analyzing $('.badge-phan-tich-container').each(function() { const $badge = $(this); if (!$badge.data('analyzing') && !$badge.hasClass('analyzing')) { $badge.css({display: 'none'}); console.log('Hiding badge:', $badge.attr('data-for')); } }); }); // Update badge position khi scroll hoặc resize (vì dùng position: fixed) function updateBadgePositions() { $('.badge-phan-tich-container:visible').each(function() { const $badge = $(this); const $parent = $badge.parent(); // Cập nhật position nếu parent đang hover HOẶC badge đang analyzing if ($parent.length && ($parent.is(':hover') || $badge.data('analyzing'))) { // Re-calculate position const offset = $parent.offset(); const scrollTop = $(window).scrollTop(); const scrollLeft = $(window).scrollLeft(); const badgeWidth = $badge.outerWidth(); $badge.css({ top: (offset.top - scrollTop) + 'px', left: (offset.left + $parent.outerWidth() - badgeWidth - scrollLeft - 5) + 'px' }); } }); } $(window).on('scroll', updateBadgePositions); $(window).on('resize', updateBadgePositions); } });