1function isDepartmentSeparator(region) { 2 return region.dep_name && region.dep_name.indexOf('---') !== -1; 3} 4 5function normalizeDepCode(code) { 6 if (code === '' || code === null || code === undefined) { 7 return ''; 8 } 9 10 const normalized = String(code).trim().toUpperCase(); 11 if (/^2[AB]$/.test(normalized) || /^97[1-6]$/.test(normalized) || /^98[4-7]$/.test(normalized)) { 12 return normalized; 13 } 14 if (/^\d$/.test(normalized)) { 15 return '0' + normalized; 16 } 17 if (/^\d+$/.test(normalized)) { 18 return normalized.padStart(2, '0'); 19 } 20 21 return normalized; 22} 23 24function parseDepartmentCounts(raw) { 25 if (!raw) { 26 return null; 27 } 28 29 try { 30 const parsed = JSON.parse(raw); 31 if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) { 32 return parsed; 33 } 34 } catch (e) { 35 return null; 36 } 37 38 return null; 39} 40 41function getConcertCountsByDepartment() { 42 const concertsSection = document.getElementById('concerts'); 43 if (concertsSection) { 44 const raw = concertsSection.getAttribute('data-department-counts') || concertsSection.dataset.departmentCounts || ''; 45 const parsed = parseDepartmentCounts(raw); 46 if (parsed) { 47 return parsed; 48 } 49 } 50 51 const dataEl = document.getElementById('concert-department-counts'); 52 if (dataEl && dataEl.textContent) { 53 const parsed = parseDepartmentCounts(dataEl.textContent); 54 if (parsed) { 55 return parsed; 56 } 57 } 58 59 const counts = {}; 60 document.querySelectorAll('.ligne_concert .concert-departement, .ligne_concert #departement').forEach(function (el) { 61 const code = normalizeDepCode(el.textContent.trim()); 62 if (code) { 63 counts[code] = (counts[code] || 0) + 1; 64 } 65 }); 66 67 return counts; 68} 69 70function getDepartmentConcertCount(region, counts) { 71 const candidates = [ 72 String(region.num_dep), 73 normalizeDepCode(region.num_dep), 74 ]; 75 76 for (let i = 0; i < candidates.length; i++) { 77 const candidate = candidates[i]; 78 if (!candidate) { 79 continue; 80 } 81 if (counts[candidate] !== undefined) { 82 return counts[candidate]; 83 } 84 if (/^\d+$/.test(candidate)) { 85 const withoutLeadingZeros = String(parseInt(candidate, 10)); 86 if (counts[withoutLeadingZeros] !== undefined) { 87 return counts[withoutLeadingZeros]; 88 } 89 } 90 } 91 92 return 0; 93} 94 95function regionMatchesFilter(region, val) { 96 if (isDepartmentSeparator(region)) { 97 return !val; 98 } 99 if (!val) { 100 return true; 101 } 102 const upperVal = val.toUpperCase(); 103 return region.dep_name.substr(0, val.length).toUpperCase() === upperVal 104 || String(region.num_dep).toUpperCase() === upperVal 105 || normalizeDepCode(region.num_dep).toUpperCase() === upperVal; 106} 107 108function sortDepartmentsByConcertCount(departments, counts) { 109 return departments.slice().sort(function (a, b) { 110 const diff = getDepartmentConcertCount(b, counts) - getDepartmentConcertCount(a, counts); 111 if (diff !== 0) { 112 return diff; 113 } 114 return a.dep_name.localeCompare(b.dep_name, 'fr'); 115 }); 116} 117 118function getRegionsForAutocomplete(regions, val) { 119 const counts = getConcertCountsByDepartment(); 120 const preferred = []; 121 const others = []; 122 let separator = null; 123 let inPreferred = true; 124 125 regions.forEach(function (region) { 126 if (isDepartmentSeparator(region)) { 127 separator = region; 128 inPreferred = false; 129 return; 130 } 131 if (!regionMatchesFilter(region, val)) { 132 return; 133 } 134 if (inPreferred) { 135 preferred.push(region); 136 } else { 137 others.push(region); 138 } 139 }); 140 141 const result = sortDepartmentsByConcertCount(preferred, counts); 142 if (!val && separator) { 143 result.push(separator); 144 } 145 return result.concat(sortDepartmentsByConcertCount(others, counts)); 146} 147 148function formatDepartmentHiddenValue(region) { 149 return region.dep_name + ' (' + region.num_dep + ')'; 150} 151 152function appendDepartmentListItems(container, regions, val, inp, onSelect, closeAllLists) { 153 const counts = getConcertCountsByDepartment(); 154 const list = getRegionsForAutocomplete(regions, val); 155 const highlightLen = val ? val.length : 0; 156 157 list.forEach(function (region) { 158 if (isDepartmentSeparator(region)) { 159 const separator = document.createElement('DIV'); 160 separator.className = 'autocomplete-separator'; 161 separator.textContent = region.dep_name; 162 container.appendChild(separator); 163 return; 164 } 165 166 const count = getDepartmentConcertCount(region, counts); 167 const item = document.createElement('DIV'); 168 let html = '<strong>[' + count + ']</strong> '; 169 html += '<strong>' + region.dep_name.substr(0, highlightLen) + '</strong>'; 170 html += region.dep_name.substr(highlightLen); 171 if (region.num_dep !== '') { 172 html += ' (' + region.num_dep + ')'; 173 } 174 html += '<input type="hidden" value="' + formatDepartmentHiddenValue(region) + '">'; 175 item.innerHTML = html; 176 item.addEventListener('click', function () { 177 inp.value = this.getElementsByTagName('input')[0].value; 178 onSelect(); 179 closeAllLists(); 180 }); 181 container.appendChild(item); 182 }); 183} 184 185function initDepartmentAutocomplete(inp, regions, onFilterChange) { 186 var currentFocus; 187 var $block = $(inp).closest('.autocomplete-block'); 188 189 function closeAllLists(elmnt) { 190 var lists = document.getElementsByClassName('autocomplete-items'); 191 for (var i = 0; i < lists.length; i++) { 192 if (elmnt !== lists[i] && elmnt !== inp) { 193 lists[i].parentNode.removeChild(lists[i]); 194 } 195 } 196 } 197 198 function openDepartmentList(val) { 199 closeAllLists(); 200 $block.find('.fa-arrow-alt-circle-up').show(); 201 $block.find('.fa-arrow-alt-circle-down').hide(); 202 203 var container = document.createElement('DIV'); 204 container.setAttribute('id', inp.id + 'autocomplete-list'); 205 container.setAttribute('class', 'autocomplete-items'); 206 inp.parentNode.appendChild(container); 207 appendDepartmentListItems(container, regions, val, inp, onFilterChange, closeAllLists); 208 } 209 210 inp.addEventListener('input', function () { 211 currentFocus = -1; 212 openDepartmentList(this.value); 213 }); 214 215 $block.find('.fa-arrow-alt-circle-down').on('click', function () { 216 openDepartmentList(inp.value); 217 }); 218 219 inp.addEventListener('focus', function () { 220 openDepartmentList(this.value); 221 }); 222 223 inp.addEventListener('keydown', function (e) { 224 var x = document.getElementById(this.id + 'autocomplete-list'); 225 if (x) { 226 x = x.getElementsByTagName('div'); 227 } 228 if (e.keyCode === 40) { 229 currentFocus++; 230 addActive(x); 231 } else if (e.keyCode === 38) { 232 currentFocus--; 233 addActive(x); 234 } else if (e.keyCode === 13) { 235 e.preventDefault(); 236 if (currentFocus > -1 && x) { 237 x[currentFocus].click(); 238 } 239 } else if (e.keyCode === 8) { 240 onFilterChange(); 241 } 242 }); 243 244 function addActive(x) { 245 if (!x || !x.length) { 246 return false;
247 } 248 removeActive(x); 249 if (currentFocus >= x.length) { 250 currentFocus = 0; 251 } 252 if (currentFocus < 0) { 253 currentFocus = (x.length - 1); 254 } 255 var attempts = 0; 256 while (x[currentFocus].classList.contains('autocomplete-separator') && attempts < x.length) { 257 currentFocus++; 258 if (currentFocus >= x.length) { 259 currentFocus = 0; 260 } 261 attempts++; 262 } 263 if (!x[currentFocus].classList.contains('autocomplete-separator')) { 264 x[currentFocus].classList.add('autocomplete-active'); 265 } 266 } 267 268 function removeActive(x) { 269 for (var i = 0; i < x.length; i++) { 270 x[i].classList.remove('autocomplete-active'); 271 } 272 } 273 274 document.addEventListener('click', function (e) { 275 if ($(e.target).hasClass('fa-arrow-alt-circle-down') === false) { 276 closeAllLists(e.target); 277 $block.find('.fa-arrow-alt-circle-up').hide(); 278 $block.find('.fa-arrow-alt-circle-down').show(); 279 } 280 }); 281 282 $(inp).on('click', function (event) { 283 event.stopPropagation(); 284 }); 285 286 $block.find('.clear').on('click', function () { 287 inp.value = ''; 288 onFilterChange(); 289 }); 290}
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.