1opensdg.dataRounding = function (value) { 2 if (value == null) { 3 return value 4 } else { 5 return Number(value.toFixed(2)) 6 } 7}; 8 9var indicatorSearch = function () { 10 var urlParams = new URLSearchParams(window.location.search); 11 var searchTerms = urlParams.get('q'); 12 13 if (searchTerms !== null) { 14 document.getElementById('search-bar-on-page').value = searchTerms; 15 document.getElementById('search-term').innerHTML = searchTerms; 16 17 var searchTermsToUse = searchTerms; 18 // This is to allow for searching by indicator with dashes. 19 if (searchTerms.split('-').length == 3 && searchTerms.length < 15) { 20 // Just a best-guess check to see if the user intended to search for an 21 // indicator ID. 22 searchTermsToUse = searchTerms.replace(/-/g, '.'); 23 } 24 25 var useLunr = typeof window.lunr !== 'undefined'; 26 if (useLunr && opensdg.language != 'en') { 27 if (typeof lunr[opensdg.language] === 'undefined') { 28 useLunr = false; 29 } 30 } 31 32 var results = []; 33 var alternativeSearchTerms = []; 34 35 if (useLunr) { 36 // Engish-specific tweak for words separated only by commas. 37 if (opensdg.language == 'en') { 38 lunr.tokenizer.separator = /[\s\-,]+/ 39 } 40 if (opensdg.language != 'en' && lunr[opensdg.language]) { 41 42 var trimmerEnRu = function (token) { 43 return token.update(function (s) { 44 return s.replace(/^[^\wа-ÑÑÐ-ЯÐ]+/, '') 45 .replace(/[^\wа-ÑÑÐ-ЯÐ]+$/, '') 46 }) 47 }; 48 49 lunr.Pipeline.registerFunction(trimmerEnRu, 'trimmer-enru'); 50 51 var stopWordFilter = lunr.generateStopWordFilter('алло без близко более болÑÑе бÑдем бÑÐ´ÐµÑ Ð±ÑдеÑе бÑдеÑÑ Ð±ÑдÑо бÑÐ´Ñ Ð±ÑдÑÑ Ð±ÑÐ´Ñ Ð±Ñ Ð±ÑÐ²Ð°ÐµÑ Ð±ÑÐ²Ñ Ð±Ñл бÑла бÑли бÑло бÑÑÑ Ð² Ð²Ð°Ð¶Ð½Ð°Ñ Ð²Ð°Ð¶Ð½Ð¾Ðµ важнÑе важнÑй вам вами Ð²Ð°Ñ Ð²Ð°Ñ Ð²Ð°Ñа ваÑе ваÑи ввеÑÑ Ð²Ð´Ð°Ð»Ð¸ вдÑÑг Ð²ÐµÐ´Ñ Ð²ÐµÐ·Ð´Ðµ веÑÑ Ð²Ð½Ð¸Ð· Ð²Ð½Ð¸Ð·Ñ Ð²Ð¾ вокÑÑг вон воÑемнадÑаÑÑй воÑемнадÑаÑÑ Ð²Ð¾ÑÐµÐ¼Ñ Ð²Ð¾ÑÑмой Ð²Ð¾Ñ Ð²Ð¿ÑоÑем вÑемени вÑÐµÐ¼Ñ Ð²Ñе вÑегда вÑего вÑем вÑеми вÑÐµÐ¼Ñ Ð²ÑÐµÑ Ð²ÑÐµÑ Ð²ÑÑ Ð²ÑÑÐ´Ñ Ð²ÑÑ Ð²ÑÑ Ð²ÑоÑой Ð²Ñ Ð³ где говоÑил говоÑÐ¸Ñ Ð³Ð¾Ð´ года Ð³Ð¾Ð´Ñ Ð´Ð° давно даже далеко далÑÑе даÑом два двадÑаÑÑй двадÑаÑÑ Ð´Ð²Ðµ двенадÑаÑÑй двенадÑаÑÑ Ð´Ð²ÑÑ Ð´ÐµÐ²ÑÑнадÑаÑÑй девÑÑнадÑаÑÑ Ð´ÐµÐ²ÑÑÑй девÑÑÑ Ð´ÐµÐ¹ÑÑвиÑелÑно дел Ð´ÐµÐ½Ñ Ð´ÐµÑÑÑÑй деÑÑÑÑ Ð´Ð»Ñ Ð´Ð¾ доволÑно долго должно дÑÑÐ³Ð°Ñ Ð´ÑÑгие дÑÑÐ³Ð¸Ñ Ð´ÑÑго дÑÑгое дÑÑгой е его ее ей ÐµÐ¼Ñ ÐµÑли еÑÑÑ ÐµÑе еÑÑ ÐµÑ ÐµÑ Ð¶ же Ð¶Ð¸Ð·Ð½Ñ Ð·Ð° занÑÑ Ð·Ð°Ð½ÑÑа занÑÑо занÑÑÑ Ð·Ð°Ñем заÑо заÑем здеÑÑ Ð·Ð½Ð°ÑÐ¸Ñ Ð¸ из или им именно имеÑÑ Ð¸Ð¼Ð¸ Ð¸Ð¼Ñ Ð¸Ð½Ð¾Ð³Ð´Ð° Ð¸Ñ Ðº ÐºÐ°Ð¶Ð´Ð°Ñ ÐºÐ°Ð¶Ð´Ð¾Ðµ каждÑе каждÑй кажеÑÑÑ ÐºÐ°Ðº ÐºÐ°ÐºÐ°Ñ ÐºÐ°ÐºÐ¾Ð¹ кем когда кого ком ÐºÐ¾Ð¼Ñ ÐºÐ¾Ð½ÐµÑно коÑоÑÐ°Ñ ÐºÐ¾ÑоÑого коÑоÑой коÑоÑÑе коÑоÑÑй коÑоÑÑÑ ÐºÑоме кÑÑгом кÑо кÑда Ð»ÐµÑ Ð»Ð¸ лиÑÑ Ð»ÑÑÑе лÑди м мало Ð¼ÐµÐ¶Ð´Ñ Ð¼ÐµÐ»Ñ Ð¼ÐµÐ½ÐµÐµ менÑÑе Ð¼ÐµÐ½Ñ Ð¼Ð¸Ð»Ð»Ð¸Ð¾Ð½Ð¾Ð² мимо миÑа мне много многоÑиÑÐ»ÐµÐ½Ð½Ð°Ñ Ð¼Ð½Ð¾Ð³Ð¾ÑиÑленное многоÑиÑленнÑе многоÑиÑленнÑй мной Ð¼Ð½Ð¾Ñ Ð¼Ð¾Ð³ могÑÑ Ð¼Ð¾Ð¶ Ð¼Ð¾Ð¶ÐµÑ Ð¼Ð¾Ð¶Ð½Ð¾ Ð¼Ð¾Ð¶Ñ Ð¾ мои мой Ð¼Ð¾Ñ Ð¼Ð¾ÑÑ Ð¼Ð¾Ñ Ð¼Ð¾Ñ Ð¼Ñ Ð½Ð° навеÑÑ Ñ Ð½Ð°Ð´ надо назад наиболее Ð½Ð°ÐºÐ¾Ð½ÐµÑ Ð½Ð°Ð¼ нами Ð½Ð°Ñ Ð½Ð°Ñала Ð½Ð°Ñ Ð½Ð°Ñа наÑе наÑи не него недавно недалеко нее ней нелÑÐ·Ñ Ð½ÐµÐ¼ немного Ð½ÐµÐ¼Ñ Ð½ÐµÐ¿ÑеÑÑвно неÑедко неÑколÑко Ð½ÐµÑ Ð½ÐµÑ Ð½ÐµÑ Ð½Ð¸ нибÑÐ´Ñ Ð½Ð¸Ð¶Ðµ низко Ð
51½Ð¸ÐºÐ¾Ð³Ð´Ð° никÑда ними Ð½Ð¸Ñ Ð½Ð¸Ñего но Ð½Ñ Ð½Ñжно Ð½Ñ Ð¾ об оба обÑÑно один одиннадÑаÑÑй одиннадÑаÑÑ Ð¾Ð´Ð½Ð°Ð¶Ð´Ñ Ð¾Ð´Ð½Ð°ÐºÐ¾ одного одной около он она они оно опÑÑÑ Ð¾Ñобенно Ð¾Ñ Ð¾ÑовÑÑÐ´Ñ Ð¾ÑÑÑда оÑÐµÐ½Ñ Ð¿ÐµÑвÑй пеÑед по под пожалÑйÑÑа позже пока Ð¿Ð¾Ñ Ð¿Ð¾Ñа поÑле поÑÑеди поÑом поÑÐ¾Ð¼Ñ Ð¿Ð¾ÑÐµÐ¼Ñ Ð¿Ð¾ÑÑи пÑекÑаÑно пÑи пÑо пÑоÑÑо пÑоÑив пÑоÑенÑов пÑÑнадÑаÑÑй пÑÑнадÑаÑÑ Ð¿ÑÑÑй пÑÑÑ Ñаз Ñазве Ñано ÑанÑÑе ÑÑдом Ñ Ñам Ñама Ñами Ñамим Ñамими ÑÐ°Ð¼Ð¸Ñ Ñамо Ñамого Ñамой Ñамом ÑÐ°Ð¼Ð¾Ð¼Ñ ÑÐ°Ð¼Ñ Ñвое Ñвоего Ñвоей Ñвои ÑÐ²Ð¾Ð¸Ñ ÑÐ²Ð¾Ñ Ñеаой Ñебе ÑÐµÐ±Ñ ÑÐµÐ³Ð¾Ð´Ð½Ñ ÑедÑмой ÑейÑÐ°Ñ ÑемнадÑаÑÑй ÑемнадÑаÑÑ ÑÐµÐ¼Ñ ÑÐ¸Ñ Ñказал Ñказала ÑказаÑÑ ÑколÑко ÑлиÑком ÑнаÑала Ñнова Ñо Ñобой ÑÐ¾Ð±Ð¾Ñ ÑовÑем ÑпаÑибо ÑÑал ÑÑÑÑ Ñ Ñа Ñак ÑÐ°ÐºÐ°Ñ Ñакже Ñакие Ñакое Ñакой Ñам Ñвой ÑÐ²Ð¾Ñ ÑÐ²Ð¾Ñ Ñе Ñебе ÑÐµÐ±Ñ Ñем Ñеми ÑепеÑÑ ÑÐµÑ Ñо Ñобой ÑÐ¾Ð±Ð¾Ñ Ñогда Ñого Ñоже ÑолÑко Ñом ÑÐ¾Ð¼Ñ ÑÐ¾Ñ ÑÐ¾Ñ ÑÑеÑий ÑÑи ÑÑинадÑаÑÑй ÑÑинадÑаÑÑ ÑÑ ÑÑда ÑÑÑ ÑÑ ÑÑÑÑÑ Ñ Ñж Ñже ÑмеÑÑ Ñ Ð¾ÑоÑо Ñ Ð¾ÑеÑÑ Ñ Ð¾ÑÑ Ñ Ð¾ÑÑ Ñ Ð¾ÑеÑÑ ÑаÑÑо ÑаÑе Ñего Ñеловек Ñем ÑÐµÐ¼Ñ ÑеÑез ÑеÑвеÑÑÑй ÑеÑÑÑе ÑеÑÑÑнадÑаÑÑй ÑеÑÑÑнадÑаÑÑ ÑÑо ÑÑоб ÑÑÐ¾Ð±Ñ ÑÑÑÑ ÑеÑÑнадÑаÑÑй ÑеÑÑнадÑаÑÑ ÑеÑÑой ÑеÑÑÑ ÑÑа ÑÑи ÑÑим ÑÑими ÑÑÐ¸Ñ ÑÑо ÑÑого ÑÑой ÑÑом ÑÑÐ¾Ð¼Ñ ÑÑÐ¾Ñ ÑÑÑ Ñ ï»¿Ð°'.split(' ')); 52 53 lunr.Pipeline.registerFunction(stopWordFilter, 'stopWordFilter-ru'); 54 } 55 56 var searchIndex = lunr(function () { 57 if (opensdg.language != 'en' && lunr[opensdg.language]) { 58 this.pipeline.reset(); 59 this.pipeline.add( 60 trimmerEnRu, 61 lunr.stopWordFilter, 62 lunr.stemmer, 63 lunr.ru.stemmer) 64 } 65 66 this.ref('url'); 67 // Index the expected fields. 68 this.field('title', getSearchFieldOptions('title')); 69 this.field('content', getSearchFieldOptions('content')); 70 this.field('id', getSearchFieldOptions('id')); 71 // Index any extra fields. 72 var i; 73 for (i = 0; i < opensdg.searchIndexExtraFields.length; i++) { 74 var extraField = opensdg.searchIndexExtraFields[i]; 75 this.field(extraField, getSearchFieldOptions(extraField)); 76 } 77 // Index all the documents. 78 for (var ref in opensdg.searchItems) { 79 this.add(opensdg.searchItems[ref]); 80 } 81 82 }); 83 // Perform the search. 84 var results = searchIndex.search(searchTermsToUse); 85 // If we didn't find anything, get progressively "fuzzier" to look for 86 // alternative search term options. 87 if (!results.length > 0) { 88 for (var fuzziness = 1; fuzziness < 5; fuzziness++) { 89 var fuzzierQuery = getFuzzierQuery(searchTermsToUse, fuzziness); 90 var alternativeResults = searchIndex.search(fuzzierQuery); 91 if (alternativeResults.length > 0) { 92 var matchedTerms = getMatchedTerms(alternativeResults); 93 if (matchedTerms) { 94 alternativeSearchTerms = matchedTerms; 95 } 96 break; 97 } 98 } 99 } 100 } else { 101 // Non-Lunr basic search functionality. 102 results = _.filter(opensdg.searchItems, function (item) { 103 var i, match = false; 104 if (item.title) { 105 match = match || item.title.indexOf(searchTermsToUse) !== -1; 106 } 107 if (item.content) { 108 match = match || item.content.indexOf(searchTermsToUse) !== -1; 109 } 110 for (i = 0; i < opensdg.searchIndexExtraFields.length; i++) { 111 var extraField = opensdg.searchIndexExtraFields[i]; 112 if (typeof item[extraField] !== 'undefined') { 113 match = match || item[extraField].indexOf(searchTermsToUse) !== -1; 114 } 115 } 116 return match; 117 });
118 // Mimic what Lunr does. 119 results = _.map(results, function (item) { 120 return {ref: item.url} 121 }); 122 } 123 124 var resultItems = []; 125 126 results.forEach(function (result) { 127 var doc = opensdg.searchItems[result.ref] 128 // Truncate the contents. 129 if (doc.content.length > 400) { 130 doc.content = doc.content.substring(0, 400) + '...'; 131 } 132 // Indicate the matches. 133 doc.content = doc.content.replace(new RegExp('(' + escapeRegExp(searchTerms) + ')', 'gi'), '<span class="match">$1</span>'); 134 doc.title = doc.title.replace(new RegExp('(' + escapeRegExp(searchTerms) + ')', 'gi'), '<span class="match">$1</span>'); 135 resultItems.push(doc); 136 }); 137 138 $('.loader').hide(); 139 140 // Print the results using a template. 141 var template = _.template( 142 $("script.results-template").html() 143 ); 144 $('div.results').html(template({ 145 searchResults: resultItems, 146 resultsCount: resultItems.length, 147 didYouMean: (alternativeSearchTerms.length > 0) ? alternativeSearchTerms : false, 148 })); 149 } 150 151 // Helper function to make a search query "fuzzier", using the ~ syntax. 152 // See https://lunrjs.com/guides/searching.html#fuzzy-matches. 153 function getFuzzierQuery(query, amountOfFuzziness) { 154 return query 155 .split(' ') 156 .map(function (x) { 157 return x + '~' + amountOfFuzziness; 158 }) 159 .join(' '); 160 } 161 162 // Helper function to get the matched words from a result set. 163 function getMatchedTerms(results) { 164 var matchedTerms = {}; 165 results.forEach(function (result) { 166 Object.keys(result.matchData.metadata).forEach(function (matchedTerm) { 167 matchedTerms[matchedTerm] = true; 168 }) 169 }); 170 return Object.keys(matchedTerms); 171 } 172 173 // Helper function to get a boost score, if any. 174 function getSearchFieldOptions(field) { 175 var opts = {} 176 if (opensdg.searchIndexBoost[field]) { 177 opts['boost'] = parseInt(opensdg.searchIndexBoost[field]) 178 } 179 return opts 180 } 181 182 // Used to highlight search term matches on the screen. 183 function escapeRegExp(str) { 184 return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/gi, "\\$&"); 185 }; 186}; 187
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.