1(function () { 2 'use strict'; 3 if (window.ccgContactFieldsReady) return; 4 window.ccgContactFieldsReady = true; 5 const lib = window.libphonenumber; 6 const root = '/data/ccguru-contact/'; 7 const ready = new WeakSet(), cache = new Map(); 8 let countries = [], sequence = 0; 9 const countryPriority = ['RU','BY','KZ','KG','TJ','UZ']; 10 const rankCountry = value => {const i=countryPriority.indexOf(countryCode(value));return i<0?99:i;}; 11 const phoneNames = new Set(['phone','mobile','fax','cphone','cc_phone','access_phone','phone_access']); 12 const cityNames = new Set(['city','ccity']); 13 const norm = value => String(value || '').trim().toLocaleLowerCase('ru').replace(/Ñ/g, 'е'); 14 function load(path) { 15 if (!cache.has(path)) cache.set(path, fetch(root + path + '?v=20260919-1', {credentials:'omit'}) 16 .then(r => { if (!r.ok) throw new Error('Dictionary unavailable'); return r.json(); }) 17 .catch(e => {cache.delete(path); throw e;})); 18 return cache.get(path); 19 } 20 function key(input) { 21 const name = input.name || ''; 22 const m = name.match(/^(.*)\[([^\]]+)\]$/); 23 return m ? {prefix:m[1], field:m[2]} : {prefix:'', field:name || input.id}; 24 } 25 function sibling(input, field) { 26 const k = key(input), scope = input.form || input.closest('[role="dialog"]') || document; 27 return Array.from(scope.querySelectorAll('input[name],select[name]')).find(el => { 28 const other = key(el); return other.prefix === k.prefix && other.field === field; 29 }); 30 } 31 function option(select, value, label) {const o = new Option(label, value); select.add(o); return o;} 32 function notify(input) {input.dispatchEvent(new Event('input',{bubbles:true})); input.dispatchEvent(new Event('change',{bubbles:true}));} 33 function label(text, control) { 34 control.id = control.id || 'ccg-contact-' + (++sequence); 35 const l = document.createElement('label');l.className='ccg-contact-label';l.htmlFor=control.id;l.textContent=text;return l; 36 } 37 function countryCode(value) { 38 const match = countries.find(c => c.iso === String(value).toUpperCase() || norm(c.name) === norm(value) || norm(c.english) === norm(value)); 39 return match ? match.iso : ''; 40 } 41 function selectCountry(input) { 42 if (ready.has(input) || input.readOnly || input.disabled) return input; 43 const current = input.value, isSelect = input.tagName === 'SELECT'; 44 const isoValues = isSelect ? Array.from(input.options).filter(o=>o.value).every(o=>/^[A-Z]{2}$/.test(o.value)) : /^[A-Z]{2}$/.test(current) || key(input).prefix==='User'; 45 const select = isSelect ? input : document.createElement('select'); 46 if (!isSelect) { 47 ['id','name','class','required','disabled','aria-describedby'].forEach(a=>{if(input.hasAttribute(a))select.setAttribute(a,input.getAttribute(a));}); 48 input.replaceWith(select); 49 } 50 const existing = new Set(Array.from(select.options).map(o=>o.value)); 51 if (!existing.has('')) option(select,'','ÐÑбеÑиÑе ÑÑÑанÑ'); 52 countries.forEach(c=>{const value=isoValues?c.iso:c.name;if(!existing.has(value))option(select,value,c.name);}); 53 if (current && !Array.from(select.options).some(o=>o.value===current)) option(select,current,current); 54 Array.from(select.options).sort((a,b)=>{if(!a.value)return -1;if(!b.value)return 1;return rankCountry(a.value)-rankCountry(b.value)||a.text.localeCompare(b.text,'ru');}).forEach(o=>select.append(o)); 55 select.value=current;Array.from(select.options).forEach(o=>o.defaultSelected=o.value===current); select.classList.add('ccg-country-select');select.autocomplete='country';ready.add(select);return select; 56 } 57 function phone(input) { 58 if (!lib || ready.has(input) || input.readOnly || input.disabled) return; 59 ready.add(input); 60 const area = key(input).field === 'phone' ? sibling(input,'phone_code_city') : null; 61 const prefix = area ? sibling(input,'phone_code_country') : null; 62 if (prefix) {splitPhone(input,prefix,area);return;} 63 input.type='tel';input.inputMode='tel';input.autocomplete='tel';input.classList.add('ccg-phone-number'); 64 input.removeAttribute('pattern');input.maxLength=Math.max(40, input.maxLength); 65 const wrap=document.createElement('div');wrap.className='ccg-phone';input.before(wrap); 66 const select=document.createElement('select');select.className='ccg-phone-country';select.setAttribute('aria-label','СÑÑана и ÑелеÑоннÑй код'); 67 phoneCountries(select);wrap.append(select,input); 68 const geo=sibling(input,'country');let iso=countryCode(geo && geo.value) || 'RU'; 69 const initial=lib.parsePhoneNumberFromString(input.value,iso); 70 if(initial && initial.country)iso=initial.country; 71 select.value=iso;
71Array.from(select.options).forEach(o=>o.defaultSelected=o.value===iso); 72 input.placeholder='+'+lib.getCountryCallingCode(iso)+' â¦'; 73 const hint=document.createElement('small');hint.className='ccg-contact-hint';hint.id='ccg-phone-hint-'+(++sequence);hint.textContent='Ðод гоÑода или опеÑаÑоÑа и Ð½Ð¾Ð¼ÐµÑ Ð°Ð±Ð¾Ð½ÐµÐ½Ñа';wrap.after(hint); 74 input.setAttribute('aria-describedby', [input.getAttribute('aria-describedby'),hint.id].filter(Boolean).join(' ')); 75 let formatting=false; 76 function format() { 77 if(formatting)return; 78 const raw=input.value;if(!raw.trim())return; 79 const caret=input.selectionStart, digitsBefore=raw.slice(0,caret).replace(/\D/g,'').length; 80 const parsed=lib.parsePhoneNumberFromString(raw,select.value); 81 // Preserve legacy extensions and unrecognised multi-number text for explicit user correction. 82 if(parsed && parsed.ext)return; 83 if(/[a-zа-Ñ,;\/]/i.test(raw))return; 84 let digits=raw.replace(/\D/g,''); 85 let international=raw.trim().startsWith('+'); 86 if(raw.startsWith('00')){digits=digits.slice(2);international=true;} 87 if(!international && ['RU','KZ'].includes(select.value) && digits.length===11 && digits[0]==='8')digits='7'+digits.slice(1),international=true; 88 if(!international){ 89 const code=lib.getCountryCallingCode(select.value); 90 // The parser removes national trunk prefixes without dropping subscriber digits. 91 if(parsed && parsed.isPossible())digits=parsed.number.slice(1); 92 else digits=code+digits; 93 } 94 const formatter=new lib.AsYouType(select.value); 95 let value=formatter.input('+'+digits); 96 const detected=formatter.getCountry();if(detected && select.querySelector('option[value="'+detected+'"]'))select.value=detected; 97 if(['RU','KZ'].includes(select.value))value=value.replace(/^(\+7) (\d{3}) (\d{3}) (\d{2}) (\d{2})$/, '$1 ($2) $3-$4-$5'); 98 formatting=true;input.value=value;formatting=false; 99 if(document.activeElement===input){
100 let target=digitsBefore+(international?0:lib.getCountryCallingCode(select.value).length), pos=0,count=0; 101 while(pos<value.length && count<target){if(/\d/.test(value[pos]))count++;pos++;} 102 input.setSelectionRange(pos,pos); 103 } 104 } 105 input.addEventListener('beforeinput',e=>{ 106 if(e.inputType!=='deleteContentBackward'||input.selectionStart!==input.selectionEnd)return; 107 let end=input.selectionStart,start=end-1; 108 if(start>=0 && /[\s()-]/.test(input.value[start])){while(start>0 && /[\s()-]/.test(input.value[start]))start--;input.setSelectionRange(start,end);} 109 }); 110 input.addEventListener('input',format); 111 if(input.form)input.form.addEventListener('reset',()=>setTimeout(format,0)); 112 select.addEventListener('change',()=>{ 113 const old=lib.parsePhoneNumberFromString(input.value); 114 if(old){input.value='+'+lib.getCountryCallingCode(select.value)+old.nationalNumber;format();notify(input);} 115 input.placeholder='+'+lib.getCountryCallingCode(select.value)+' â¦';input.focus(); 116 }); 117 // Render existing valid numbers; no input/change event and no persistence on page load. 118 if(initial && initial.isPossible() && !initial.ext){input.value=initial.formatInternational();format();} 119 const group=input.closest('.form-group'); 120 if(group)group.querySelectorAll('.help-block').forEach(el=>{if(el.textContent.includes('+XXX'))el.textContent='ÐÑбеÑиÑе ÑÑÑÐ°Ð½Ñ Ð¸ ÑкажиÑе Ð½Ð¾Ð¼ÐµÑ ÑелеÑона.';}); 121 } 122 function phoneCountries(select) { 123 const supported=new Set(lib.getCountries()); 124 countries.filter(c=>supported.has(c.iso)).forEach(c=>option(select,c.iso,c.name+' (+'+lib.getCountryCallingCode(c.iso)+')')); 125 } 126 function splitPhone(input,prefix,area) { 127 ready.add(prefix);ready.add(area); 128 const select=document.createElement('select');select.className=(prefix.className||'')+' ccg-phone-country';select.setAttribute('aria-label','СÑÑана и ÑелеÑоннÑй код');phoneCountries(select); 129 const code=String(prefix.value||'7').replace(/\D/g,''); 130 const candidate=countries.find(c=>lib.getCountries().includes(c.iso)&&lib.getCountryCallingCode(c.iso)===code); 131 const parsed=lib.parsePhoneNumberFromString('+'+code+area.value.replace(/\D/g,'')+input.value.replace(/\D/g,'')); 132 select.value=parsed&&parsed.country?parsed.country:code==='7'?'RU':candidate?candidate.iso:'RU';Array.from(select.options).forEach(o=>o.defaultSelected=o.selected); 133 prefix.before(select);if(!prefix.value)prefix.value='+7';prefix.type='hidden';prefix.removeAttribute('required'); 134 select.addEventListener('change',()=>{prefix.value='+'+lib.getCountryCallingCode(select.value);notify(prefix);}); 135 [area,input].forEach(el=>{el.type='tel';el.inputMode='numeric';el.classList.add('ccg-phone-number');el.removeAttribute('pattern');el.style.width='100%';}); 136 if(area.id){const areaLabel=document.querySelector('label[for="'+CSS.escape(area.id)+'"]');if(areaLabel)areaLabel.textContent='Ðод гоÑода / опеÑаÑоÑа';} 137 area.placeholder='Ðод гоÑода / опеÑаÑоÑа';input.placeholder='ÐÐ¾Ð¼ÐµÑ Ð°Ð±Ð¾Ð½ÐµÐ½Ñа'; 138 area.addEventListener('input',()=>{area.value=area.value.replace(/\D/g,'');}); 139 input.addEventListener('input',()=>{ 140 const d=input.value.replace(/\D/g,''); 141 // Existing schema stores country/area/subscriber separately. 142 input.value=d.length===7?d.replace(/^(\d{3})(\d{2})(\d{2})$/,'$1-$2-$3'):d.replace(/(\d{3})(?=\d)/g,'$1 '); 143 }); 144 } 145 async function explicitGeo(city) { 146 if(ready.has(city)||city.disabled||city.readOnly)return; 147 ready.add(city); 148 const country=selectCountry(sibling(city,'country')),region=sibling(city,'region'); 149 if(!country||!region)return; 150 ready.add(region); 151 const saved={region:region.value,city:city.value}; 152 const regionGroup=region.closest('.form-group')||region.parentElement; 153 const regionSelect=document.createElement('select');regionSelect.className='form-control ccg-region-select'; 154 regionSelect.id=region.id+'-dictionary';region.before(regionSelect);region.type='hidden'; 155 const regionLabel=regionGroup.querySelector('label[for="'+CSS.escape(region.id)+'"]');if(regionLabel)regionLabel.htmlFor=regionSelect.id; 156 const otherRegion=document.createElement('input');otherRegion.type='text';otherRegion.className='form-control ccg-geo-other';otherRegion.maxLength=255; 157 region.after(label('ÐÑÑгой Ñегион:',otherRegion),otherRegion); 158 const cityInput=document.createElement('input');cityInput.className='form-control ccg-city-input';cityInput.autocomplete='off';cityInput.id=city.id+'-dictionary'; 159 city.before(cityInput);city.type='hidden'; 160 const cityGroup=city.closest('.form-group')||city.parentElement; 161 const cityLabel=cityGroup.querySelector('label[for="'+CSS.escape(city.id)+'"]');if(cityLabel)cityLabel.htmlFor=cityInput.id; 162 const list=document.createElement('datalist');list.id='ccg-cities-'+(++sequence);cityInput.setAttribute('list',list.id);cityInput.after(list); 163 const otherCity=document.createElement('input');otherCity.type='text';otherCity.className='form-control ccg-geo-other';otherCity.maxLength=255; 164 city.after(label('ÐÑÑгой гоÑод:',otherCity),otherCity); 165 const hint=document.createElement('small');hint.className='ccg-contact-hint';hint.setAttribute('role','status');otherCity.after(hint); 166 const credit=document.createElement('small');credit.className='ccg-geo-credit'; 167 const creditLink=document.createElement('a');creditLink.href='https://www.geonames.org/';creditLink.target='_blank';creditLink.rel='noopener';creditLink.textContent='СпÑавоÑник GeoNames';credit.append(creditLink);hint.after(credit); 168 let groups=[],regions=[],items=[],version=0;
169 const knownRegion=r=>r.id!=='_' && r.name && !/^Регион\s/.test(r.name); 170 function addSuggestions(){ 171 list.replaceChildren();const q=norm(cityInput.value); 172 items.filter(r=>!q||norm(r[2]).includes(q)).slice(0,100).forEach(r=>{const o=document.createElement('option');o.value=r[1];list.append(o);}); 173 } 174 function restoreCity(){ 175 const known=items.find(r=>norm(r[1])===norm(city.value)); 176 cityInput.value=known?known[1]:'';otherCity.value=known?'':city.value;addSuggestions(); 177 } 178 async function towns(clear){ 179 const ticket=++version,c=countryCode(country.value); 180 items=[];list.replaceChildren(); 181 if(clear){city.value='';cityInput.value='';otherCity.value='';notify(city);} 182 if(!c){hint.textContent='ÐÑбеÑиÑе ÑÑÑанÑ.';return;} 183 hint.textContent='ÐагÑÑжаем наÑелÑннÑе пÑнкÑÑâ¦'; 184 const selected=regions.find(r=>r.name===regionSelect.value); 185 const sources=selected?[selected]:groups; 186 try { 187 const results=await Promise.all(sources.map(r=>load(c+'/'+r.id+'.json'))); 188 if(ticket!==version||!city.isConnected)return; 189 const unique=new Map();results.forEach(rows=>rows.forEach(r=>{if(!unique.has(r[0]))unique.set(r[0],r);}));items=Array.from(unique.values()); 190 const priority=r=>c==='RU'?(Number(r[0])===524901?0:Number(r[0])===498817?1:2):2; 191 items.sort((a,b)=>priority(a)-priority(b)||a[1].localeCompare(b[1],'ru')); 192 restoreCity();hint.textContent=items.length?'ÐÑбеÑиÑе гоÑод из подÑказок. ÐÑли его неÑ, заполниÑе «ÐÑÑгой гоÑод».':'Ð ÑпÑавоÑнике Ð½ÐµÑ Ð³Ð¾Ñодов. ÐаполниÑе «ÐÑÑгой гоÑод».'; 193 } catch(e){if(ticket===version){restoreCity();hint.textContent='СпÑавоÑник вÑеменно недоÑÑÑпен. ÐоÑод можно ÑказаÑÑ Ð² поле «ÐÑÑгой гоÑод».';}} 194 } 195 async function update(clear){ 196 const ticket=++version,c=countryCode(country.value); 197 groups=[];regions=[];items=[];regionGroup.hidden=false;regionSelect.replaceChildren();option(regionSelect,'','ÐÑе ÑÐµÐ³Ð¸Ð¾Ð½Ñ / дÑÑгой Ñегион'); 198 if(clear){region.value='';otherRegion.value='';city.value='';cityInput.value='';otherCity.value='';notify(region);notify(city);} 199 else {otherRegion.value=region.value;otherCity.value=city.value;} 200 list.replaceChildren(); 201 if(!c){hint.textContent='ÐÑбеÑиÑе ÑÑÑанÑ.';return;} 202 hint.textContent='ÐагÑÑжаем ÑегионÑâ¦'; 203 try { 204 const loaded=await load(c+'/regions.json');if(ticket!==version||!city.isConnected)return;groups=loaded; 205 regions=groups.filter(knownRegion);regions.forEach(r=>option(regionSelect,r.name,r.name)); 206 const selected=regions.find(r=>norm(r.name)===norm(region.value)||norm(r.english)===norm(region.value)||r.id===region.value); 207 regionSelect.value=selected?selected.name:'';otherRegion.value=selected?'':region.value; 208 regionGroup.hidden=regions.length===0; 209 await towns(false); 210 } catch(e){if(ticket===version)hint.textContent='СпÑавоÑник вÑеменно недоÑÑÑпен. ÐаполниÑе Ð¿Ð¾Ð»Ñ Â«ÐÑÑгой Ñегион» и «ÐÑÑгой гоÑод».';} 211 } 212 country.addEventListener('change',()=>update(true)); 213 regionSelect.addEventListener('change',()=>{region.value=regionSelect.value;otherRegion.value='';notify(region);towns(true);}); 214 otherRegion.addEventListener('input',()=>{ 215 const previous=regionSelect.value;regionSelect.value='';region.value=otherRegion.value;notify(region); 216 if(previous)towns(true); 217 }); 218 cityInput.addEventListener('input',()=>{otherCity.value='';city.value=cityInput.value;notify(city);addSuggestions();}); 219 cityInput.addEventListener('change',()=>{
220 const known=items.find(r=>norm(r[1])===norm(cityInput.value)); 221 if(!known&&cityInput.value){otherCity.value=cityInput.value;cityInput.value='';addSuggestions();} 222 }); 223 otherCity.addEventListener('input',()=>{cityInput.value='';city.value=otherCity.value;notify(city);addSuggestions();}); 224 if(city.form)city.form.addEventListener('reset',()=>setTimeout(()=>{region.value=saved.region;city.value=saved.city;update(false);},0)); 225 await update(false); 226 } 227 async function geo(city) { 228 if(city.hasAttribute('data-ccg-explicit-geo'))return explicitGeo(city); 229 if(ready.has(city)||city.disabled||city.readOnly)return;ready.add(city); 230 let country=sibling(city,'country'),region=sibling(city,'region'); 231 const box=document.createElement('div');box.className='ccg-geo-assist'; 232 // Add selectors only where the original schema has no corresponding fields. 233 city.before(box); 234 if(country)country=selectCountry(country); 235 else {country=document.createElement('select');option(country,'','ÐÑбеÑиÑе ÑÑÑанÑ');countries.forEach(c=>option(country,c.iso,c.name));box.append(label('СÑÑана',country),country);ready.add(country);} 236 let originalRegion=region;const initialRegion=region?region.value:''; 237 if(region && region.tagName!=='SELECT'){ 238 const replacement=document.createElement('select'); 239 ['id','name','class','required','disabled','aria-describedby'].forEach(a=>{if(region.hasAttribute(a))replacement.setAttribute(a,region.getAttribute(a));}); 240 if(region.value)option(replacement,region.value,region.value);replacement.value=region.value;region.replaceWith(replacement);region=replacement; 241 } 242 if(!region){region=document.createElement('select');box.append(label('ÐблаÑÑÑ / Ñегион',region),region);} 243 ready.add(region);region.classList.add('ccg-region-select'); 244 if(!originalRegion && key(city).prefix==='User'){ 245 region.addEventListener('change',()=>{region.name='User[region]';}); 246 country.addEventListener('change',()=>{region.name='User[region]';}); 247 } 248 const list=document.createElement('datalist');list.id='ccg-cities-'+(++sequence);city.classList.add('ccg-city-input');city.setAttribute('list',list.id);city.autocomplete='off';city.after(list); 249 const hint=document.createElement('small');hint.className='ccg-contact-hint';hint.setAttribute('role','status');list.after(hint); 250 const credit=document.createElement('small');credit.className='ccg-geo-credit'; 251 const creditLink=document.createElement('a');creditLink.href='https://www.geonames.org/';creditLink.target='_blank';creditLink.rel='noopener';creditLink.textContent='СпÑавоÑник GeoNames';credit.append(creditLink);hint.after(credit); 252 let regions=[],items=[],prominent=[],version=0; 253 function suggestions(){ 254 const q=norm(city.value);list.replaceChildren(); 255 items.filter(r=>!q||norm(r[2]).includes(q)).slice(0,80).forEach(r=>{const o=document.createElement('option');o.value=r[1];list.append(o);}); 256 } 257 async function towns(clear){ 258 const v=++version;items=[];list.replaceChildren();if(clear){city.value='';notify(city);} 259 const c=countryCode(country.value),r=region.value && regions.find(r=>norm(r.name)===norm(region.value) || norm(r.english)===norm(region.value) || r.id===region.value); 260 if(!c||!r){ 261 if(c==='RU'){try{prominent=await load('RU/prominent.json');if(v!==version)return;items=prominent;suggestions();}catch(e){}} 262 hint.textContent='ÐÑбеÑиÑе Ñегион или один из пÑедложеннÑÑ Ð³Ð¾Ñодов.';return; 263 } 264 hint.textContent='ÐагÑÑжаем наÑелÑннÑе пÑнкÑÑâ¦'; 265 try{const rows=await load(c+'/'+r.id+'.json');if(v!==version||!city.isConnected)return;items=rows;suggestions();hint.textContent='ÐаÑниÑе вводиÑÑ Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ðµ. ÐÑли его Ð
265½ÐµÑ в ÑпиÑке, ÑÐ¾Ñ ÑаниÑе ÑÐ²Ð¾Ñ Ð·Ð½Ð°Ñение.';} 266 catch(e){if(v===version)hint.textContent='СпиÑок вÑеменно недоÑÑÑпен. Ðазвание можно ввеÑÑи вÑÑÑнÑÑ.';} 267 } 268 async function update(clear){ 269 const v=++version,c=countryCode(country.value),old=clear?'':region.value; 270 items=[];list.replaceChildren();regions=[];region.replaceChildren();option(region,'','ÐÑбеÑиÑе облаÑÑÑ / Ñегион'); 271 if(old)option(region,old,old),region.value=old; 272 if(clear){city.value='';notify(city);if(originalRegion)region.dispatchEvent(new Event('input',{bubbles:true}));} 273 if(!c){hint.textContent='ÐÑбеÑиÑе ÑÑÑÐ°Ð½Ñ Ð´Ð»Ñ Ð¿Ð¾Ð¸Ñка Ñегиона и наÑелÑнного пÑнкÑа.';return;} 274 try{ 275 const data=await load(c+'/regions.json');if(v!==version||!city.isConnected)return;regions=data; 276 data.forEach(r=>{if(norm(r.name)!==norm(old))option(region,r.name,r.name);});region.value=old; 277 if(data.length===1&&!old){region.value=data[0].name;if(originalRegion)region.dispatchEvent(new Event('input',{bubbles:true}));} 278 await towns(false); 279 }catch(e){if(v===version)hint.textContent='СпÑавоÑник вÑеменно недоÑÑÑпен. Ð¡Ð¾Ñ ÑанÑннÑе даннÑе оÑÑÐ°Ð²Ð»ÐµÐ½Ñ Ð±ÐµÐ· изменений.';} 280 } 281 country.addEventListener('change',()=>update(true));region.addEventListener('change',()=>towns(true));city.addEventListener('input',suggestions); 282 city.addEventListener('change',()=>{ 283 if(countryCode(country.value)!=='RU'||region.value)return; 284 const chosen=prominent.find(r=>norm(r[1])===norm(city.value)); 285 if(chosen){const r=regions.find(r=>r.id===chosen[4]);if(r){region.value=r.name;if(key(city).prefix==='User'&&!originalRegion)region.name='User[region]';towns(false);}} 286 }); 287 if(city.form)city.form.addEventListener('reset',()=>setTimeout(()=>{ 288 if(initialRegion && !Array.from(region.options).some(o=>o.value===initialRegion))option(region,initialRegion,initialRegion); 289 region.value=initialRegion;update(false); 290 },0)); 291 await update(false); 292 } 293 function scan(scope) { 294 scope.querySelectorAll('.ccg-phone').forEach(w=>{const i=w.querySelector('input'),s=w.querySelector('select');if(i&&s&&s.disabled!==(i.disabled||i.readOnly))s.disabled=i.disabled||i.readOnly;}); 295 const inputs=Array.from(scope.querySelectorAll('input,select')); 296 inputs.filter(el=>el.type!=='hidden'&&key(el).field==='country'&&!/(Search|Filter)/i.test(key(el).prefix)).forEach(selectCountry); 297 inputs.filter(el=>el.tagName==='INPUT'&&el.type!=='hidden'&&(phoneNames.has(key(el).field)||el.type==='tel')) 298 .filter(el=>!/(Search|Filter)/i.test(key(el).prefix)).forEach(phone); 299 inputs.filter(el=>el.tagName==='INPUT'&&cityNames.has(key(el).field)&&el.type!=='hidden') 300 .filter(el=>!/(Search|Filter)/i.test(key(el).prefix)).forEach(geo); 301 } 302 load('countries.json').then(data=>{ 303 countries=data;countries.sort((a,b)=>rankCountry(a.iso)-rankCountry(b.iso)||a.name.localeCompare(b.name,'ru'));scan(document); 304 let scheduled=false; 305 new MutationObserver(records=>{ 306 if(!records.some(r=>r.type==='attributes'||Array.from(r.addedNodes).some(n=>n.nodeType===1&&(n.matches('input,select,form')||n.querySelector('input,select')))))return; 307 if(!scheduled){scheduled=true;setTimeout(()=>{scheduled=false;scan(document);},0);} 308 }).observe(document.documentElement,{childList:true,subtree:true,attributes:true,attributeFilter:['disabled','readonly']}); 309 }).catch(()=>{/* Native existing controls stay usable when dictionaries cannot be loaded. */}); 310})();
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.