Publish Vulpes Preview 15 sources for desktop, Android and Tundra

Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
OverSu 2026-09-30 23:13:03 +02:00
commit b38dea0597
25901 changed files with 9982925 additions and 369 deletions

View file

@ -0,0 +1,288 @@
/* global debug */
/* exported AutoSettings */
'use strict';
var AutoSettings = (function() {
var OPTION_CONFIGURERS = {
'select': function _selectConfigurer(guiWidget) {
var optionName = guiWidget.dataset.option;
var span, parent = guiWidget.parentElement;
if (parent.classList.contains('fake-select')) {
var firstChild = parent.firstChild;
if (!firstChild || firstChild.tagName !== 'SPAN') {
span = document.createElement('span');
parent.insertBefore(span, parent.firstChild);
}
}
guiWidget.addEventListener('blur', function _onSelectChange() {
debug('Value:', guiWidget.value);
settings.option(optionName, guiWidget.value);
});
settings.observe(optionName, function _onOptionChange(value) {
if (value === undefined) {
value = settings.defaultValue(optionName);
}
guiWidget.value = value;
if (span) {
var selected = guiWidget.options[guiWidget.selectedIndex];
var l10nId = selected.getAttribute('data-l10n-id');
span.textContent = selected.textContent;
if (l10nId) {
span.setAttribute('data-l10n-id', l10nId);
}
}
});
},
// Select is used to simulate custom combo boxes. It displays a selection
// dialog with an ok button and possibly a cancel button. The value is only
// changed if ok button is pressed. If cancel provided and clicked then
// the former value is restored.
'customselect': function _customselectConfigurer(guiWidget) {
var dialog = document.getElementById(guiWidget.dataset.selectdialog);
var optionName = guiWidget.dataset.option;
// Dialog
var okButton = dialog.querySelector('button.recommend');
if (okButton) {
okButton.addEventListener('click', function _onDialogOk() {
var checked = dialog.querySelector('input[type="radio"]:checked');
settings.option(optionName, checked.value);
vmanager.closeCurrentView();
});
}
var cancelButton = dialog.querySelector('button.cancel');
if (cancelButton) {
cancelButton.addEventListener('click',
function _onDialogCancel() {
var currentValue = settings.option(optionName);
settings.option(optionName, currentValue);
vmanager.closeCurrentView();
}
);
}
guiWidget.addEventListener('click', function _onWidgetClick() {
vmanager.changeViewTo(dialog.id);
});
// Keep the widget and the dialog synchronized
settings.observe(optionName,
function _onOptionChange(value) {
// Use default value if no value
if (value === null || value === undefined) {
value = getDefaultValue(optionName);
}
var radio =
dialog.querySelector('input[type="radio"][value="' + value + '"]');
if (!radio) {
value = getDefaultValue(optionName);
radio = dialog.querySelector('input[type="radio"][value="' +
value + '"]');
}
radio.checked = true;
var textSpan = dialog.querySelector('input:checked + span');
var tagSpan = guiWidget.querySelector('.tag');
tagSpan.textContent = textSpan.textContent;
}
);
// Keep the UI localized
window.addEventListener('localized', function _onLocalized() {
var textSpan = dialog.querySelector('input:checked + span');
var tagSpan = guiWidget.querySelector('.tag');
tagSpan.textContent = textSpan.textContent;
});
},
// Switch configurer handles an checkbox. When it changes, the checked
// state is used as the content for the option.
'switch' : function _switchConfigurer(guiWidget) {
var optionName = guiWidget.dataset.option;
// Add an observer to keep synchronization
settings.observe(
optionName,
function _onOptionChange(value) {
if (value === null || value === undefined) {
value = getDefaultValue(optionName);
}
guiWidget.checked = value;
}
);
// Add an event listener to switch the option
guiWidget.addEventListener('change', function ccapp_onSwitchChange() {
settings.option(optionName, guiWidget.checked);
});
},
// Input configurer handles an input box. When the content changes, the
// content is parsed and sent to the proper option.
'input' : function _inputConfigurer(guiWidget) {
var optionName = guiWidget.dataset.option;
// Add an observer to keep synchronization
settings.observe(
optionName,
function _onOptionChange(value) {
if (value === null || value === undefined) {
value = getDefaultValue(optionName);
}
guiWidget.value = value;
}
);
// Add an event listener to switch the option
guiWidget.addEventListener('change', function _onContentChange() {
var value = guiWidget.value;
if (guiWidget.type === 'number') {
value = parseFloat(value);
}
settings.option(optionName, value);
});
}
};
// Add a new type with its configuration function
function addType(newType, configFunction) {
OPTION_CONFIGURERS[newType] = configFunction;
}
var customRecognizer;
// Add a recognizer to detect new types
function setCustomRecognizer(recognizer) {
customRecognizer = recognizer;
}
// Return the <li> wrapping the option
function getEntryParent(item) {
while (item && item.tagName !== 'LI') {
item = item.parentNode;
}
return item;
}
// Return the default value for an option
function getDefaultValue(optionName) {
return settings.defaultValue(optionName);
}
// Configure the web page
var settings, vmanager;
function initialize(settingsInterface, viewManager, root) {
root = root || 'body';
settings = settingsInterface;
vmanager = viewManager;
// Return the type of configurer needed based on the properties of
// the HTML element marked as the option.
function getWidgetType(widget) {
if (widget.dataset.widgetType) {
return widget.dataset.widgetType;
}
var customType;
if (customRecognizer === 'function') {
customType = customRecognizer(widget, settings, vmanager);
}
if (customType) {
return customType;
}
if (widget.tagName === 'SELECT') {
return 'select';
}
if (typeof widget.dataset.selectdialog !== 'undefined') {
return 'customselect';
}
if (widget.type === 'checkbox' ||
widget.nodeName.toLowerCase() === 'gaia-switch') {
return 'switch';
}
if (['text', 'number'].indexOf(widget.type) !== -1) {
return 'input';
}
}
// Install a dependency based on an expression. When expression is true
// call the callback.
function installDependency(expression, callback) {
var equality = false;
var parsed = expression.split('!=');
if (parsed.length === 1) {
parsed = expression.split('=');
equality = true;
}
var dependency = parsed[0];
var referenceValue = parsed[1];
settings.observe(dependency,
function ccapp_dependencyAction(value) {
var test = (('' + value) === referenceValue);
callback(equality === test); // or is an equality test and values are
// equal or is an inequality test and
// values are different.
}
);
}
// Widgets
var allGUIWidgets = document.querySelectorAll(root + ' .settings-option');
[].forEach.call(allGUIWidgets, function _forEachWidget(guiWidget) {
var type = getWidgetType(guiWidget);
var entry = getEntryParent(guiWidget);
var configurer = OPTION_CONFIGURERS[type];
if (configurer) {
configurer(guiWidget, settings, vmanager, root);
}
// Simple dependency resolution:
// enable / disable some options depending on the values of other
var disableOn = guiWidget.dataset.disableOn;
if (disableOn) {
installDependency(disableOn, function _disable(passed) {
guiWidget.disabled = passed;
if (entry) {
entry.setAttribute('aria-disabled', passed + '');
}
});
}
// hide / show some options depending on the values of other
var hideOn = guiWidget.dataset.hideOn;
if (hideOn) {
installDependency(hideOn, function _hide(passed) {
guiWidget.hidden = passed;
if (entry) {
entry.hidden = passed;
}
});
}
});
}
return {
initialize: initialize,
setCustomRecognizer: setCustomRecognizer,
addType: addType
};
}());

View file

@ -0,0 +1,234 @@
/* global _, addNetworkUsageAlarm, Common, Formatting, SimManager,
CostControl */
/* exported dataLimitConfigurer */
'use strict';
function dataLimitConfigurer(guiWidget, settings, viewManager, widgetRoot) {
var REMOVE_CHAR_CODE = 8,
// It Represents any positive real number (up to three digits length),
// with optional decimal point, accepting up to 2 decimal places. It is
// not necessary adding the significant number when it is zero (eg. '.5'
// is a valid entry)
DATA_LIMIT_NUMERIC_FORMAT = new RegExp('^[0-9]{0,3}(\\.[0-9]{1,2})?$');
var dialog = document.getElementById('data-limit-dialog');
var dataLimitInput = dialog.querySelector('input');
var format = function ccal_formatterDataUnit(value) {
var unit = settings.option('dataLimitUnit');
return Formatting.formatData([value, _(unit)]);
};
window.addEventListener('localized', function _onLocalize() {
var tagSpan = guiWidget.querySelector('.tag');
tagSpan.textContent = format(dataLimitInput.value);
});
// Configure dialog
var okButton = dialog.querySelector('button.recommend');
if (okButton) {
okButton.addEventListener('click', function ccld_onDialogOk() {
var value = parseFloat(dataLimitInput.value);
settings.option('dataLimitValue', value);
settings.option('dataLimitUnit', currentUnit);
var dataLimit = Common.getDataLimit({'dataLimitValue': value,
'dataLimitUnit': currentUnit});
SimManager.requestDataSimIcc(function(dataSim) {
var simInterface = Common.getDataSIMInterface(dataSim.iccId);
addNetworkUsageAlarm(simInterface, dataLimit, null,
() => checkDataLimit(dataLimit));
});
viewManager.closeCurrentView();
});
}
var dialogHeader = dialog.querySelector('#limit-dialog-header');
if (dialogHeader) {
dialogHeader.addEventListener('action',
function ccld_onDialogCancel() {
var oldValue = settings.option('dataLimitValue');
var oldUnit = settings.option('dataLimitUnit');
currentUnit = oldUnit;
settings.option('dataLimitValue', oldValue);
settings.option('dataLimitUnit', oldUnit);
dataLimitInput.classList.remove('error');
okButton.disabled = false;
viewManager.closeCurrentView();
}
);
}
function checkDataLimit(dataLimit) {
CostControl.getInstance(function _onCostControl(costcontrol) {
var requestObj = {
type: 'datausage'
};
costcontrol.request(requestObj, function _onDataStats(result) {
var stats = result.data.mobile.total;
if (stats > dataLimit) {
var mobileUsage = {
limit: Formatting.formatData(Formatting.roundData(dataLimit))
};
var message = _('data-limit-notification-title2', mobileUsage) +
'\n' + _('data-limit-notification-text2');
window.alert(message);
}
});
});
}
function isNotRemovingChar(newChar) {
return REMOVE_CHAR_CODE !== newChar;
}
function isAllowedValue(newValue) {
return isValidValue(newValue) || wouldBeValid(newValue);
}
// Checks if value is numeric and it has a valid format
// Not allowed entry characters '-', ',' or more than one '.'
function isValidValue(newValue) {
var containsNonValidCharacters = [',','-']
.some(c => newValue.indexOf(c) > -1);
var containsMoreThanOneDot = (newValue.match(/\./g) || []).length > 1;
return !Number.isNaN(newValue) &&
!containsNonValidCharacters && !containsMoreThanOneDot &&
isValidFormat(newValue);
}
function wouldBeValid(lowLimitValue) {
var allowedEntry = new RegExp('^0?(\\.0?)?$');
return allowedEntry.test(lowLimitValue);
}
function preventBadInput(valid, newChar, currentInput) {
// This method returns the string resultant of adding the character of the
// keypress event
function simulateNewValue(newChar, currentInput) {
var value = currentInput.value,
idx = currentInput.selectionStart,
newCharValue = String.fromCharCode(newChar);
return value.substr(0, idx) + newCharValue + value.substr(idx);
}
var newValue = simulateNewValue(newChar, currentInput);
var isInvalid = !valid(newValue);
return isInvalid;
}
dataLimitInput.addEventListener('keypress',
function cc_onKeypress(event) {
var currentInput = event.target;
var newChar = event.charCode || event.keyCode;
// If the entry is not valid or the result of the input is invalid, we
// have to prevent the event propagation
if (isNotRemovingChar(newChar) &&
preventBadInput(isAllowedValue, newChar, currentInput)) {
event.preventDefault();
event.stopPropagation();
return;
}
}
);
function isValidFormat(lowLimitValue) {
var numberDataLimit = Number(lowLimitValue);
return (numberDataLimit < 1000 &&
numberDataLimit > 0 &&
DATA_LIMIT_NUMERIC_FORMAT.test(numberDataLimit));
}
// Disable OK button when dataLimitInput not matches any positive real number
// (up to three digits length), with optional decimal point, accepting up
// to 2 decimal places.
dataLimitInput.addEventListener('input',
function cc_ondataLimitInputChange(evt) {
var lowLimitValue = evt.target.value.trim();
var isNumericLowLimit = !Number.isNaN(Number(lowLimitValue));
if (isNumericLowLimit &&
lowLimitValue.indexOf('.0') !== lowLimitValue.length - 2 &&
lowLimitValue.indexOf('.') !== lowLimitValue.length - 1) {
dataLimitInput.value = Number(lowLimitValue);
}
var isValidValue = (isNumericLowLimit && isValidFormat(lowLimitValue));
if (isValidValue) {
dataLimitInput.classList.remove('error');
} else {
dataLimitInput.classList.add('error');
}
okButton.disabled = (!isValidValue);
}
);
// Configure the swicth unit button
var currentUnit = settings.option('dataLimitUnit');
var switchUnitButton = dialog.querySelector('.switch-unit-button');
function localizeSwitchUnitButton(unit) {
switchUnitButton.setAttribute('data-l10n-id', 'unit-' + unit);
switchUnitButton.querySelector('span.tag').setAttribute(
'data-l10n-id', unit);
}
localizeSwitchUnitButton(currentUnit);
switchUnitButton.addEventListener('click',
function ccapp_switchUnit() {
currentUnit = (currentUnit === 'MB') ? 'GB' : 'MB';
localizeSwitchUnitButton(currentUnit);
}
);
// Prevent to loose the focus when tapping on switch unit button
// TODO: Replace with 'focusout' on dataLimitInput when fixing bug:
// https://bugzilla.mozilla.org/show_bug.cgi?id=687787
switchUnitButton.addEventListener('mousedown',
function _preventFocusLost(evt) {
evt.preventDefault();
}
);
// Keep the widget and the dialog synchronized
settings.observe('dataLimitValue',
function ccld_onValueChange(value) {
// Use default value if no value
if (value === null || typeof value === 'undefined') {
value = settings.defaultValue('dataLimitValue');
}
// Set dialog
dataLimitInput.value = value;
var tagSpan = guiWidget.querySelector('.tag');
tagSpan.textContent = format(dataLimitInput.value);
}
);
settings.observe('dataLimitUnit',
function ccld_onUnitChange(value) {
// Use default value if no value
if (value === null || typeof value === 'undefined') {
value = settings.defaultValue('dataLimitUnit');
}
// Set dialog
localizeSwitchUnitButton(value);
var tagSpan = guiWidget.querySelector('.tag');
tagSpan.textContent = format(dataLimitInput.value);
}
);
// Show the dialog
var oldUnitValue;
guiWidget.addEventListener('click', function ccld_onWidgetClick() {
viewManager.changeViewTo(dialog.id, widgetRoot);
dataLimitInput.focus();
dataLimitInput.setSelectionRange(dataLimitInput.value.length,
dataLimitInput.value.length);
oldUnitValue = settings.option('dataLimitUnit');
localizeSwitchUnitButton(oldUnitValue);
});
}

View file

@ -0,0 +1,12 @@
;'use strict';var NetworkUsageAlarm=(function(){function _addAlarm(networkInterface,value,onsuccess,onerror){if(!networkInterface){console.error('Error, the network interface is not defined when trying '+'to add an alarm');(typeof onerror==='function')&&onerror();return;}
if(value===null||typeof value==='undefined'){console.error('Limit value is undefined, impossible add an alarm');(typeof onerror==='function')&&onerror();return;}
var request=navigator.mozNetworkStats.addAlarm(networkInterface,value);request.onsuccess=onsuccess;request.onerror=function error(e){console.error('Error, when trying to addAlarm to the interfaceId: '+
networkInterface.id+' and limit: '+value);(typeof onerror==='function')&&onerror();};}
function _clearAlarms(networkInterface,callback){if(!networkInterface){console.error('Error, the network interface is not defined when trying '+'to remove alarms');return;}
var request=navigator.mozNetworkStats.getAllAlarms(networkInterface);request.onsuccess=function success(){var alarmList=request.result;var pendingRequest=alarmList.length;function checkForCompletion(){pendingRequest--;if(pendingRequest===0){(typeof callback==='function')&&callback();}}
function _onErrorRemoveAlarm(){console.error('Error when trying to remove one alarm.');checkForCompletion();}
for(var i=0;i<alarmList.length;i++){if(alarmList[i]&&alarmList[i].alarmId){var rA=navigator.mozNetworkStats.removeAlarms(alarmList[i].alarmId);rA.onsuccess=checkForCompletion;rA.onerror=_onErrorRemoveAlarm;}}
if(pendingRequest===0){(typeof callback==='function')&&callback();}};request.onerror=function error(){console.error('Error when trying to get alarms from the API to clear it');};}
function _updateAlarm(dataInterface,value,onsuccess,onerror){if(dataInterface&&value){var addNewAlarm=_addAlarm.bind(null,dataInterface,value,onsuccess,onerror);_clearAlarms(dataInterface,addNewAlarm);}else{if(!dataInterface){console.error('Error, the network interface is not defined when '+'trying to update an alarm');}else{console.error('Error, the data limit value is not defined when '+'trying to update an alarm');}
(typeof onerror==='function')&&onerror();}}
return{updateAlarm:_updateAlarm,clearAlarms:_clearAlarms};}());

View file

@ -0,0 +1,19 @@
;'use strict';var ConfigManager=window.parent.ConfigManager;var CostControl=window.parent.CostControl;var SimManager=window.parent.SimManager;var Common=window.parent.Common;var NetworkUsageAlarm=window.parent.NetworkUsageAlarm;var addNetworkUsageAlarm=window.parent.addNetworkUsageAlarm;var resetTelephony=window.parent.resetTelephony;navigator.mozL10n=window.parent.navigator.mozL10n;var DEBUGGING=window.parent.DEBUGGING;var debug=window.parent.debug;var Settings=(function(){var costcontrol,vmanager,initialized,endLoadSettingsNotified;var plantypeSelector,phoneActivityTitle,phoneActivitySettings;var balanceTitle,balanceSettings,reportsTitle;var balanceView,resetMenuDialog,confirmDialog;function configureUI(){CostControl.getInstance(function _onCostControl(instance){costcontrol=instance;if(DEBUGGING){loadDeveloperAids();}
vmanager=new ViewManager();plantypeSelector=document.getElementById('plantype-settings');phoneActivityTitle=document.getElementById('phone-activity-settings');phoneActivitySettings=document.querySelector('#phone-activity-settings + .settings');balanceTitle=document.getElementById('balance-settings');balanceSettings=document.querySelector('#balance-settings + .settings');reportsTitle=document.getElementById('phone-internet-settings');var balanceConfig=ConfigManager.configuration.balance;balanceView=new BalanceView(document.getElementById('balance'),document.querySelector('#balance + .meta'),balanceConfig?balanceConfig.minimum_delay:undefined);var resetDialog=document.getElementById('reset-dialog');var resetDataDialog=document.getElementById('reset-data-dialog');resetMenuDialog=new ResetMenuDialog(resetDataDialog,vmanager);confirmDialog=new ConfirmDialog(resetDialog,vmanager);resetMenuDialog.initializeResetModes(confirmDialog);AutoSettings.addType('data-limit',dataLimitConfigurer);AutoSettings.initialize(ConfigManager,vmanager,'#settings-view');configureTelephonyReset();configureDataResets();addDoneConstrains();ConfigManager.observe('dataLimit',function _onDataLimitChange(value,old,key,settings){SimManager.requestDataSimIcc(function(dataSim){var iccId=dataSim.iccId;var currentDataInterface=Common.getDataSIMInterface(iccId);if(!value){NetworkUsageAlarm.clearAlarms(currentDataInterface);}else{addNetworkUsageAlarm(currentDataInterface,Common.getDataLimit(settings));}});},true);ConfigManager.observe('plantype',updateUI,true);ConfigManager.observe('lastTelephonyActivity',function _updateTelephony(activity,old,key,settings){updateTelephony(activity,settings.lastTelephonyReset);},true);ConfigManager.observe('lastDataUsage',function _updateDataUsage(stats,old,key,settings){updateDataUsage(stats,settings.lastCompleteDataReset);},true);ConfigManager.observe('lastBalance',function _updateBalance(balance){updateBalance(balance,balance.currency);},true);var close=document.getElementById('close-settings');close.addEventListener('click',function(){closeSettings();});function _setResetTimeToDefault(value,old,key,settings){var today=new Date();var defaultResetTime=(settings.trackingPeriod==='weekly')?today.getDay():today.getDate();if(settings.resetTime!==defaultResetTime){ConfigManager.setOption({resetTime:defaultResetTime});}else{Common.updateNextReset(settings.trackingPeriod,settings.resetTime);}}
function _updateNextReset(value,old,key,settings){Common.updateNextReset(settings.trackingPeriod,settings.resetTime);}
ConfigManager.observe('resetTime',_updateNextReset,true);ConfigManager.observe('trackingPeriod',_setResetTimeToDefault,true);initialized=true;Settings.updateUI();});}
function closeSettings(){window.parent.location.hash='#';}
function loadDeveloperAids(){var xhr=new XMLHttpRequest();xhr.overrideMimeType('text/plain');xhr.open('GET','/debug.html',false);xhr.send();if(xhr.status===200){var src=document.createElement('DIV');src.innerHTML=xhr.responseText;var reference=document.getElementById('plantype-settings');var parent=reference.parentNode;[].forEach.call(src.childNodes,function(node){reference=parent.insertBefore(node,reference.nextSibling);});}}
function configureTelephonyReset(){var resetTelephonyButton=document.getElementById('reset-telephony');resetTelephonyButton.addEventListener('click',function(){confirmDialog.setMessage('reset-telephony-confirmation-warning',{});function resetAction(){resetTelephony();updateUI();confirmDialog.closeConfirmDialog();}
confirmDialog.updateAcceptAction(resetAction);confirmDialog.showConfirmDialog();});}
function configureDataResets(){var resetDataUsage=document.getElementById('reset-data-usage');resetDataUsage.addEventListener('click',function _onDataReset(){var currentTotals={mobile:costcontrol.lastDataResults.mobile.total,wifi:costcontrol.lastDataResults.wifi.total};resetMenuDialog.showResetMenuDialog(currentTotals);});}
var balanceLowLimitView;function addDoneConstrains(){var closeButton=document.getElementById('close-settings');balanceLowLimitView=new BalanceLowLimitView(document.getElementById('low-limit'),document.getElementById('low-limit-input'));balanceLowLimitView.onvalidation=function(evt){closeButton.disabled=!evt.isValid;};}
window.addEventListener('localized',function _onLocalize(){if(initialized){updateUI();}});var currentMode;function updateUI(){ConfigManager.requestAll(function _onInfo(configuration,settings){Common.localizeWeekdaySelector(document.getElementById('select-weekday'));var mode=ConfigManager.getApplicationMode();if(currentMode!==mode){currentMode=mode;var hidePlantypeSelector=(mode==='DATA_USAGE_ONLY');var hidePhoneActivity=(mode!=='POSTPAID');var hideBalance=(mode!=='PREPAID');var hideReportsTitle=(mode==='PREPAID');var textReportsTitle=(mode==='POSTPAID')?'phone-and-internet-data-report':'internet-data-report';reportsTitle.querySelector('span').setAttribute('data-l10n-id',textReportsTitle);balanceLowLimitView.disabled=(mode!=='PREPAID');plantypeSelector.hidden=hidePlantypeSelector;phoneActivityTitle.hidden=hidePhoneActivity;phoneActivitySettings.hidden=hidePhoneActivity;balanceTitle.hidden=hideBalance;balanceSettings.hidden=hideBalance;reportsTitle.hidden=hideReportsTitle;}
var requestObj={type:'datausage'};costcontrol.request(requestObj,function _onDataStats(result){var stats=result.data;updateDataUsage(stats,settings.lastCompleteDataReset);});switch(mode){case'PREPAID':updateBalance(settings.lastBalance,configuration.credit.currency);break;case'POSTPAID':updateTelephony(settings.lastTelephonyActivity,settings.lastTelephonyReset);break;}
if(endLoadSettingsNotified){window.performance.measure('loadSettings','loadSettingsStart');endLoadSettingsNotified=true;}});}
function updateDataUsage(datausage,lastCompleteDataReset){var mobileUsage=document.querySelector('#mobile-data-usage > span');var data=Formatting.roundData(datausage.mobile.total);mobileUsage.textContent=Formatting.formatData(data);var wifiUsage=document.querySelector('#wifi-data-usage > span');data=Formatting.roundData(datausage.wifi.total);wifiUsage.textContent=Formatting.formatData(data);updateDataUsageTimestamp(lastCompleteDataReset,datausage.timestamp);}
var dataUsagePeriod={begin:null,end:null};function updateDataUsageTimestamp(begin,end){dataUsagePeriod.begin=begin;dataUsagePeriod.end=end;var timestamp=document.querySelector('#wifi-data-usage + .meta');timestamp.innerHTML='';timestamp.appendChild(Formatting.formatTimeHTML(begin,end));}
function updateBalance(lastBalance,currency){var limitCurrency=document.getElementById('settings-low-limit-currency');limitCurrency.textContent=currency;balanceView.update(lastBalance);}
function updateTelephony(activity,lastTelephonyReset){var calltimeSpan=document.getElementById('calltime');var smscountSpan=document.getElementById('smscount');Common.localize(calltimeSpan,'magnitude',{value:Formatting.computeTelephonyMinutes(activity),unit:'min.'});Common.localize(smscountSpan,'magnitude',{value:activity.smscount,unit:'SMS'});updateTelephonyTimestamp(lastTelephonyReset,activity.timestamp);}
var telephonyPeriod={begin:null,end:null};function updateTelephonyTimestamp(begin,end){telephonyPeriod.begin=begin;telephonyPeriod.end=end;var timestamp=document.getElementById('telephony-timestamp');timestamp.innerHTML='';timestamp.appendChild(Formatting.formatTimeHTML(begin,end));}
window.addEventListener('timeformatchange',function(){updateTelephonyTimestamp(telephonyPeriod.begin,telephonyPeriod.end);updateDataUsageTimestamp(dataUsagePeriod.begin,dataUsagePeriod.end);});return{initialize:function(){var SCRIPTS_NEEDED=['js/utils/toolkit.js','shared/js/date_time_helper.js','js/utils/formatting.js','js/views/BalanceLowLimitView.js','js/settings/limitdialog.js','js/settings/autosettings.js','js/view_manager.js','js/views/BalanceView.js','js/views/ResetMenuDialog.js','js/views/ConfirmDialog.js'];LazyLoader.load(SCRIPTS_NEEDED,function(){if(!Common.allNetworkInterfaceLoaded){Common.loadNetworkInterfaces(configureUI);}else{configureUI();}});},updateUI:updateUI};}());Settings.initialize();