您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Parses a text string into hours, for use in Waze Map Editor scripts
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.cn-greasyfork.org/scripts/38249/249737/WME%20Utils%20-%20HoursParser%20Beta.js
// ==UserScript== // @name WME Utils - HoursParser Beta // @namespace WazeDev // @version 2018.02.08.001 // @description Parses a text string into hours, for use in Waze Map Editor scripts // @author MapOMatic (originally developed by bmtg) // @license GNU GPLv3 // ==/UserScript== class HoursParser { constructor() { let currLocale = I18n.translations[I18n.currentLocale()]; var I18nDate = currLocale.date; this.DAYS_OF_THE_WEEK = { SS: ['saturdays', I18nDate.day_names[6].toLowerCase(), 'satur', I18nDate.abbr_day_names[6].toLowerCase(), 'sa'], UU: ['sundays', I18nDate.day_names[0].toLowerCase(), I18nDate.abbr_day_names[0].toLowerCase(), 'su'], MM: ['mondays', I18nDate.day_names[1].toLowerCase(), 'mondy', I18nDate.abbr_day_names[1].toLowerCase(), 'mo'], TT: ['tuesdays', I18nDate.day_names[2].toLowerCase(), 'tues', I18nDate.abbr_day_names[2].toLowerCase(), 'tu'], WW: ['wednesdays', I18nDate.day_names[3].toLowerCase(), 'weds', I18nDate.abbr_day_names[3].toLowerCase(), 'we'], RR: ['thursdays', I18nDate.day_names[4].toLowerCase(), 'thurs', 'thur', I18nDate.abbr_day_names[4].toLowerCase(), 'th'], FF: ['fridays', I18nDate.day_names[5].toLowerCase(), I18nDate.abbr_day_names[5].toLowerCase(), 'fr'] }; this.MONTHS_OF_THE_YEAR = { JAN: [I18nDate.month_names[1].toLowerCase(), I18nDate.abbr_month_names[1].toLowerCase()], FEB: [I18nDate.month_names[2].toLowerCase(), 'febr', I18nDate.abbr_month_names[2].toLowerCase()], MAR: [I18nDate.month_names[3].toLowerCase(), I18nDate.abbr_month_names[3].toLowerCase()], APR: [I18nDate.month_names[4].toLowerCase(), I18nDate.abbr_month_names[4].toLowerCase()], MAY: [I18nDate.month_names[5].toLowerCase(), I18nDate.abbr_month_names[5].toLowerCase()], JUN: [I18nDate.month_names[6].toLowerCase(), I18nDate.abbr_month_names[6].toLowerCase()], JUL: [I18nDate.month_names[7].toLowerCase(), I18nDate.abbr_month_names[7].toLowerCase()], AUG: [I18nDate.month_names[8].toLowerCase(), I18nDate.abbr_month_names[8].toLowerCase()], SEP: [I18nDate.month_names[9].toLowerCase(), 'sept', I18nDate.abbr_month_names[9].toLowerCase()], OCT: [I18nDate.month_names[10].toLowerCase(), I18nDate.abbr_month_names[10].toLowerCase()], NOV: [I18nDate.month_names[11].toLowerCase(), I18nDate.abbr_month_names[11].toLowerCase()], DEC: [I18nDate.month_names[12].toLowerCase(), I18nDate.abbr_month_names[12].toLowerCase()] }; this.DAY_CODE_VECTOR = ['MM','TT','WW','RR','FF','SS','UU','MM','TT','WW','RR','FF','SS','UU','MM','TT','WW','RR','FF']; this.THRU_WORDS = ['through','thru',currLocale.element_history.changed_to,'until','till','til','-','~'].map(x => x = "\b" + x + "\b"); } parseHours(inputHours, locale) { let returnVal = { hours: [], parseError: false, overlappingHours: false, sameOpenAndCloseTimes: false }; let tfHourTemp, tfDaysTemp, newDayCodeVec = []; let tempRegex, twix, tsix; let inputHoursParse = inputHours.toLowerCase().trim(); if (inputHoursParse.length === 0 || inputHoursParse === ',') { return returnVal; } let today = new Date(); let tomorrow = new Date(); tomorrow.setDate(tomorrow.getDate() + 1); inputHoursParse = inputHoursParse.replace(/\btoday\b/g, today.toLocaleDateString(locale, {weekday:'short'}).toLowerCase()) .replace(/\btomorrow\b/g, tomorrow.toLocaleDateString(locale, {weekday:'short'}).toLowerCase()) .replace(/\u2013|\u2014/g, "-") // long dash replacing .replace(/[^a-z0-9\:\-\. ~áé]/g, ' ') // replace unnecessary characters with spaces .replace(/\:{2,}/g, ':') // remove extra colons .replace(/closed|not open/g, '99:99-99:99') // parse 'closed' .replace(/by appointment( only)?/g, '99:99-99:99') // parse 'appointment only' .replace(/weekdays/g, 'mon-fri').replace(/weekends/g, 'sat-sun') // convert weekdays and weekends to days .replace(/(12(:00)?\W*)?noon/g, "12:00").replace(/(12(:00)?\W*)?mid(night|nite)/g, "00:00") // replace 'noon', 'midnight' .replace(/every\s*day|daily|(7|seven) days a week/g, "mon-sun") // replace 'seven days a week' .replace(/(open\s*)?(24|twenty\W*four)\W*h(ou)?rs?|all day/g, "00:00-00:00") // replace 'open 24 hour or similar' .replace(/(\D:)([^ ])/g, "$1 $2"); // space after colons after words // replace thru type words with dashes this.THRU_WORDS.forEach(word => { inputHoursParse = inputHoursParse.replace( new RegExp(word, 'g'), '-'); }); inputHoursParse = inputHoursParse.replace(/\-{2,}/g, "-"); // replace any duplicate dashes // kill extra words let killWords = 'paste|here|business|operation|times|time|walk-ins|walk ins|welcome|dinner|lunch|brunch|breakfast|regular|weekday|weekend|opening|open|now|from|hours|hour|our|are|EST|and|&'.split("|"); for (twix=0; twix<killWords.length; twix++) { tempRegex = new RegExp('\\b'+killWords[twix]+'\\b', "g"); inputHoursParse = inputHoursParse.replace(tempRegex,''); } // replace day terms with double caps for (let dayKey in this.DAYS_OF_THE_WEEK) { if (this.DAYS_OF_THE_WEEK.hasOwnProperty(dayKey)) { let tempDayList = this.DAYS_OF_THE_WEEK[dayKey]; for (var tdix=0; tdix<tempDayList.length; tdix++) { tempRegex = new RegExp(tempDayList[tdix]+'(?!a-z)', "g"); inputHoursParse = inputHoursParse.replace(tempRegex,dayKey); } } } // Replace dates for (let monthKey in this.MONTHS_OF_THE_YEAR) { if (this.MONTHS_OF_THE_YEAR.hasOwnProperty(monthKey)) { let tempMonthList = this.MONTHS_OF_THE_YEAR[monthKey]; for (var tmix=0; tmix<tempMonthList.length; tmix++) { tempRegex = new RegExp(tempMonthList[tmix]+'\\.? ?\\d{1,2}\\,? ?201\\d{1}', "g"); inputHoursParse = inputHoursParse.replace(tempRegex,' '); tempRegex = new RegExp(tempMonthList[tmix]+'\\.? ?\\d{1,2}', "g"); inputHoursParse = inputHoursParse.replace(tempRegex,' '); } } } // replace any periods between hours with colons inputHoursParse = inputHoursParse.replace(/(\d{1,2})\.(\d{2})/g, '$1:$2'); // remove remaining periods inputHoursParse = inputHoursParse.replace(/\./g, ''); // remove any non-hour colons between letters and numbers and on string ends inputHoursParse = inputHoursParse.replace(/(\D+)\:(\D+)/g, '$1 $2').replace(/^ *\:/g, ' ').replace(/\: *$/g, ' '); // replace am/pm with AA/PP inputHoursParse = inputHoursParse.replace(/ *pm/g,'PP').replace(/ *am/g,'AA'); inputHoursParse = inputHoursParse.replace(/ *p\.m\./g,'PP').replace(/ *a\.m\./g,'AA'); inputHoursParse = inputHoursParse.replace(/ *p\.m/g,'PP').replace(/ *a\.m/g,'AA'); inputHoursParse = inputHoursParse.replace(/ *p/g,'PP').replace(/ *a/g,'AA'); // tighten up dashes inputHoursParse = inputHoursParse.replace(/\- {1,}/g,'-').replace(/ {1,}\-/g,'-'); inputHoursParse = inputHoursParse.replace(/^(00:00-00:00)$/g,'MM-UU$1'); // Change all MTWRFSU to doubles, if any other letters return false if (inputHoursParse.match(/[bcdeghijklnoqvxyz]/g) !== null) { returnVal.parseError = true; return returnVal; } else { inputHoursParse = inputHoursParse.replace(/m/g,'MM').replace(/t/g,'TT').replace(/w/g,'WW').replace(/r/g,'RR'); inputHoursParse = inputHoursParse.replace(/f/g,'FF').replace(/s/g,'SS').replace(/u/g,'UU'); } // tighten up spaces inputHoursParse = inputHoursParse.replace(/ {2,}/g,' '); inputHoursParse = inputHoursParse.replace(/ {1,}AA/g,'AA'); inputHoursParse = inputHoursParse.replace(/ {1,}PP/g,'PP'); // Expand hours into XX:XX format for (var asdf=0; asdf<5; asdf++) { // repeat a few times to catch any skipped regex matches inputHoursParse = inputHoursParse.replace(/([^0-9\:])(\d{1})([^0-9\:])/g, '$10$2:00$3'); inputHoursParse = inputHoursParse.replace(/^(\d{1})([^0-9\:])/g, '0$1:00$2'); inputHoursParse = inputHoursParse.replace(/([^0-9\:])(\d{1})$/g, '$10$2:00'); inputHoursParse = inputHoursParse.replace(/([^0-9\:])(\d{2})([^0-9\:])/g, '$1$2:00$3'); inputHoursParse = inputHoursParse.replace(/^(\d{2})([^0-9\:])/g, '$1:00$2'); inputHoursParse = inputHoursParse.replace(/([^0-9\:])(\d{2})$/g, '$1$2:00'); inputHoursParse = inputHoursParse.replace(/(\D)(\d{1})(\d{2}\D)/g, '$10$2:$3'); inputHoursParse = inputHoursParse.replace(/^(\d{1})(\d{2}\D)/g, '0$1:$2'); inputHoursParse = inputHoursParse.replace(/(\D)(\d{1})(\d{2})$/g, '$10$2:$3'); inputHoursParse = inputHoursParse.replace(/(\D\d{2})(\d{2}\D)/g, '$1:$2'); inputHoursParse = inputHoursParse.replace(/^(\d{2})(\d{2}\D)/g, '$1:$2'); inputHoursParse = inputHoursParse.replace(/(\D\d{2})(\d{2})$/g, '$1:$2'); inputHoursParse = inputHoursParse.replace(/(\D)(\d{1}\:)/g, '$10$2'); inputHoursParse = inputHoursParse.replace(/^(\d{1}\:)/g, '0$1'); } // replace 12AM range with 00 inputHoursParse = inputHoursParse.replace( /12(\:\d{2}AA)/g, '00$1'); // Change PM hours to 24hr time while (inputHoursParse.match(/\d{2}\:\d{2}PP/) !== null) { tfHourTemp = inputHoursParse.match(/(\d{2})\:\d{2}PP/)[1]; tfHourTemp = parseInt(tfHourTemp) % 12 + 12; inputHoursParse = inputHoursParse.replace(/\d{2}(\:\d{2})PP/,tfHourTemp.toString()+'$1'); } // kill the AA inputHoursParse = inputHoursParse.replace( /AA/g, ''); // Side check for tabular input var inputHoursParseTab = inputHoursParse.replace( /[^A-Z0-9\:-]/g, ' ').replace( / {2,}/g, ' '); inputHoursParseTab = inputHoursParseTab.replace( /^ +/g, '').replace( / {1,}$/g, ''); if (inputHoursParseTab.match(/[A-Z]{2}\:?\-? [A-Z]{2}\:?\-? [A-Z]{2}\:?\-? [A-Z]{2}\:?\-? [A-Z]{2}\:?\-?/g) !== null) { inputHoursParseTab = inputHoursParseTab.split(' '); var reorderThree = [0,7,14,1,8,15,2,9,16,3,10,17,4,11,18,5,12,19,6,13,20]; var reorderTwo = [0,7,1,8,2,9,3,10,4,11,5,12,6,13]; var inputHoursParseReorder = [], reix; if (inputHoursParseTab.length === 21) { for (reix=0; reix<21; reix++) { inputHoursParseReorder.push(inputHoursParseTab[reorderThree[reix]]); } } else if (inputHoursParseTab.length === 18) { for (reix=0; reix<18; reix++) { inputHoursParseReorder.push(inputHoursParseTab[reorderThree[reix]]); } } else if (inputHoursParseTab.length === 15) { for (reix=0; reix<15; reix++) { inputHoursParseReorder.push(inputHoursParseTab[reorderThree[reix]]); } } else if (inputHoursParseTab.length === 14) { for (reix=0; reix<14; reix++) { inputHoursParseReorder.push(inputHoursParseTab[reorderTwo[reix]]); } } else if (inputHoursParseTab.length === 12) { for (reix=0; reix<12; reix++) { inputHoursParseReorder.push(inputHoursParseTab[reorderTwo[reix]]); } } else if (inputHoursParseTab.length === 10) { for (reix=0; reix<10; reix++) { inputHoursParseReorder.push(inputHoursParseTab[reorderTwo[reix]]); } } if (inputHoursParseReorder.length > 9) { inputHoursParseReorder = inputHoursParseReorder.join(' '); inputHoursParseReorder = inputHoursParseReorder.replace(/(\:\d{2}) (\d{2}\:)/g, '$1-$2'); inputHoursParse = inputHoursParseReorder; } } // remove colons after Days field inputHoursParse = inputHoursParse.replace(/(\D+)\:/g, '$1 '); // Find any double sets inputHoursParse = inputHoursParse.replace(/([A-Z \-]{2,}) *(\d{2}\:\d{2} *\-{1} *\d{2}\:\d{2}) *(\d{2}\:\d{2} *\-{1} *\d{2}\:\d{2})/g, '$1$2$1$3'); inputHoursParse = inputHoursParse.replace(/(\d{2}\:\d{2}) *(\d{2}\:\d{2})/g, '$1-$2'); // remove all spaces inputHoursParse = inputHoursParse.replace( / */g, ''); // Remove any dashes acting as Day separators for 3+ days ("M-W-F") inputHoursParse = inputHoursParse.replace( /([A-Z]{2})-([A-Z]{2})-([A-Z]{2})-([A-Z]{2})-([A-Z]{2})-([A-Z]{2})-([A-Z]{2})/g, '$1$2$3$4$5$6$7'); inputHoursParse = inputHoursParse.replace( /([A-Z]{2})-([A-Z]{2})-([A-Z]{2})-([A-Z]{2})-([A-Z]{2})-([A-Z]{2})/g, '$1$2$3$4$5$6'); inputHoursParse = inputHoursParse.replace( /([A-Z]{2})-([A-Z]{2})-([A-Z]{2})-([A-Z]{2})-([A-Z]{2})/g, '$1$2$3$4$5'); inputHoursParse = inputHoursParse.replace( /([A-Z]{2})-([A-Z]{2})-([A-Z]{2})-([A-Z]{2})/g, '$1$2$3$4'); inputHoursParse = inputHoursParse.replace( /([A-Z]{2})-([A-Z]{2})-([A-Z]{2})/g, '$1$2$3'); // parse any 'through' type terms on the day ranges (MM-RR --> MMTTWWRR) while (inputHoursParse.match(/[A-Z]{2}\-[A-Z]{2}/) !== null) { tfDaysTemp = inputHoursParse.match(/([A-Z]{2})\-([A-Z]{2})/); var startDayIX = this.DAY_CODE_VECTOR.indexOf(tfDaysTemp[1]); newDayCodeVec = [tfDaysTemp[1]]; for (var dcvix=startDayIX+1; dcvix<startDayIX+7; dcvix++) { newDayCodeVec.push(this.DAY_CODE_VECTOR[dcvix]); if (tfDaysTemp[2] === this.DAY_CODE_VECTOR[dcvix]) { break; } } newDayCodeVec = newDayCodeVec.join(''); inputHoursParse = inputHoursParse.replace(/[A-Z]{2}\-[A-Z]{2}/,newDayCodeVec); } // split the string between numerical and letter characters inputHoursParse = inputHoursParse.replace(/([A-Z])\-?\:?([0-9])/g,'$1|$2'); inputHoursParse = inputHoursParse.replace(/([0-9])\-?\:?([A-Z])/g,'$1|$2'); inputHoursParse = inputHoursParse.replace(/(\d{2}\:\d{2})\:00/g,'$1'); // remove seconds inputHoursParse = inputHoursParse.split("|"); var daysVec = [], hoursVec = []; for (tsix=0; tsix<inputHoursParse.length; tsix++) { if (inputHoursParse[tsix][0].match(/[A-Z]/) !== null) { daysVec.push(inputHoursParse[tsix]); } else if (inputHoursParse[tsix][0].match(/[0-9]/) !== null) { hoursVec.push(inputHoursParse[tsix]); } else { returnVal.parseError = true; return returnVal; } } // check that the dayArray and hourArray lengths correspond if ( daysVec.length !== hoursVec.length ) { returnVal.parseError = true; return returnVal; } // Combine days with the same hours in the same vector var newDaysVec = [], newHoursVec = [], hrsIX; for (tsix=0; tsix<daysVec.length; tsix++) { if (hoursVec[tsix] !== '99:99-99:99') { // Don't add the closed days hrsIX = newHoursVec.indexOf(hoursVec[tsix]); if (hrsIX > -1) { newDaysVec[hrsIX] = newDaysVec[hrsIX] + daysVec[tsix]; } else { newDaysVec.push(daysVec[tsix]); newHoursVec.push(hoursVec[tsix]); } } } var hoursObjectArray = [], hoursObjectArrayMinDay = [], hoursObjectArraySorted = [], hoursObjectAdd, daysObjArray, toFromSplit; for (tsix=0; tsix<newDaysVec.length; tsix++) { hoursObjectAdd = {}; daysObjArray = []; toFromSplit = newHoursVec[tsix].match(/(\d{2}\:\d{2})\-(\d{2}\:\d{2})/); if (toFromSplit === null) { returnVal.parseError = true; return returnVal; } else { // Check for hours outside of 0-23 and 0-59 var hourCheck = toFromSplit[1].match(/(\d{2})\:/)[1]; if (hourCheck>23 || hourCheck < 0) { returnVal.parseError = true; return returnVal; } hourCheck = toFromSplit[2].match(/(\d{2})\:/)[1]; if (hourCheck>23 || hourCheck < 0) { returnVal.parseError = true; return returnVal; } hourCheck = toFromSplit[1].match(/\:(\d{2})/)[1]; if (hourCheck>59 || hourCheck < 0) { returnVal.parseError = true; return returnVal; } hourCheck = toFromSplit[2].match(/\:(\d{2})/)[1]; if (hourCheck>59 || hourCheck < 0) { returnVal.parseError = true; return returnVal; } } // Make the days object if ( newDaysVec[tsix].indexOf('MM') > -1 ) { daysObjArray.push(1); } if ( newDaysVec[tsix].indexOf('TT') > -1 ) { daysObjArray.push(2); } if ( newDaysVec[tsix].indexOf('WW') > -1 ) { daysObjArray.push(3); } if ( newDaysVec[tsix].indexOf('RR') > -1 ) { daysObjArray.push(4); } if ( newDaysVec[tsix].indexOf('FF') > -1 ) { daysObjArray.push(5); } if ( newDaysVec[tsix].indexOf('SS') > -1 ) { daysObjArray.push(6); } if ( newDaysVec[tsix].indexOf('UU') > -1 ) { daysObjArray.push(0); } // build the hours object hoursObjectAdd.fromHour = toFromSplit[1]; hoursObjectAdd.toHour = toFromSplit[2]; hoursObjectAdd.days = daysObjArray.sort(); hoursObjectArray.push(hoursObjectAdd); // track the order if (hoursObjectAdd.days.length > 1 && hoursObjectAdd.days[0] === 0) { hoursObjectArrayMinDay.push( hoursObjectAdd.days[1] * 100 + parseInt(toFromSplit[1][0])*10 + parseInt(toFromSplit[1][1]) ); } else { hoursObjectArrayMinDay.push( (((hoursObjectAdd.days[0]+6)%7)+1) * 100 + parseInt(toFromSplit[1][0])*10 + parseInt(toFromSplit[1][1]) ); } } this._sortWithIndex(hoursObjectArrayMinDay); for (var hoaix=0; hoaix < hoursObjectArrayMinDay.length; hoaix++) { hoursObjectArraySorted.push(hoursObjectArray[hoursObjectArrayMinDay.sortIndices[hoaix]]); } if ( !this._checkHours(hoursObjectArraySorted) ) { returnVal.hours = hoursObjectArraySorted; returnVal.overlappingHours = true; return returnVal; } else if ( this._hasSameOpenCloseTimes(hoursObjectArraySorted) ) { returnVal.hours = hoursObjectArraySorted; returnVal.sameOpenAndCloseTimes = true; return returnVal; } else { for ( var ohix=0; ohix<hoursObjectArraySorted.length; ohix++ ) { if ( hoursObjectArraySorted[ohix].days.length === 2 && hoursObjectArraySorted[ohix].days[0] === 0 && hoursObjectArraySorted[ohix].days[1] === 1) { // separate hours hoursObjectArraySorted.push({days: [0], fromHour: hoursObjectArraySorted[ohix].fromHour, toHour: hoursObjectArraySorted[ohix].toHour}); hoursObjectArraySorted[ohix].days = [1]; } } } returnVal.hours = hoursObjectArray; return returnVal; } // function to check overlapping hours _checkHours(hoursObj) { if (hoursObj.length === 1) { return true; } var daysObj, fromHourTemp, toHourTemp; for (var day2Ch=0; day2Ch<7; day2Ch++) { // Go thru each day of the week daysObj = []; for ( var hourSet = 0; hourSet < hoursObj.length; hourSet++ ) { // For each set of hours if (hoursObj[hourSet].days.indexOf(day2Ch) > -1) { // pull out hours that are for the current day, add 2400 if it goes past midnight, and store fromHourTemp = hoursObj[hourSet].fromHour.replace(/\:/g,''); toHourTemp = hoursObj[hourSet].toHour.replace(/\:/g,''); if (toHourTemp <= fromHourTemp) { toHourTemp = parseInt(toHourTemp) + 2400; } daysObj.push([fromHourTemp, toHourTemp]); } } if (daysObj.length > 1) { // If there's multiple hours for the day, check them for overlap for ( var hourSetCheck2 = 1; hourSetCheck2 < daysObj.length; hourSetCheck2++ ) { for ( var hourSetCheck1 = 0; hourSetCheck1 < hourSetCheck2; hourSetCheck1++ ) { if ( daysObj[hourSetCheck2][0] > daysObj[hourSetCheck1][0] && daysObj[hourSetCheck2][0] < daysObj[hourSetCheck1][1] ) { return false; } if ( daysObj[hourSetCheck2][1] > daysObj[hourSetCheck1][0] && daysObj[hourSetCheck2][1] < daysObj[hourSetCheck1][1] ) { return false; } } } } } return true; } _hasSameOpenCloseTimes(hoursObj) { var fromHourTemp, toHourTemp; for ( var hourSet = 0; hourSet < hoursObj.length; hourSet++ ) { // For each set of hours fromHourTemp = hoursObj[hourSet].fromHour; toHourTemp = hoursObj[hourSet].toHour; if (fromHourTemp !== '00:00' && fromHourTemp === toHourTemp) { // If open and close times are the same, don't parse. return true; } } return false; } _sortWithIndex(toSort) { for (var i = 0; i < toSort.length; i++) { toSort[i] = [toSort[i], i]; } toSort.sort(function(left, right) { return left[0] < right[0] ? -1 : 1; }); toSort.sortIndices = []; for (var j = 0; j < toSort.length; j++) { toSort.sortIndices.push(toSort[j][1]); toSort[j] = toSort[j][0]; } return toSort; } // delete this later... _unused() {} }