Erster Commit: nativer Linux-Port aus macOS-Bytecode

Läuft die Voice Acoustic VA-Remotecontrol (AllDSP AllControl) nativ unter Linux
auf echtem wxGTK 3.0 — ohne Wine und ohne dekompilierten App-Code. Ausgeführt wird
das unveränderte Python-2.7-Bytecode aus dem macOS-.app; C-Extensions (wxGTK/numpy/
scipy/PortAudio) kommen nativ aus Debian stretch.

Enthält: va/ (Original-.pyc + pure-Python-Libs + Assets + launch.py mit den drei
Linux-Fixes), Dockerfile/run.sh/entrypoint.sh, reference/ (dekompilierter Quellcode
zum Debuggen) und README/STATUS. img.cache (378 MB, regenerierbar) ist per
.gitignore ausgeschlossen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
maik
2026-08-20 19:57:01 +02:00
co-authored by Claude Opus 4.8
commit a7c93fa266
654 changed files with 478133 additions and 0 deletions
+712
View File
@@ -0,0 +1,712 @@
# uncompyle6 version 3.9.3
# Python bytecode version base 2.6 (62161)
# Decompiled from: Python 3.9.25 (main, Oct 31 2025, 23:16:49)
# [GCC 14.2.0]
# Embedded file name: user_config.pyc
# Compiled at: 2024-12-11 13:13:37
import wx, os, data_model, traceback, one_unit, ConfigParser, protocol, sys, select_keys, select_units, d_protocol, mytime, user_config_dc, user_config_keys, user_config_leds, user_config_audio, user_config_model, user_config_various, user_config_network, user_config_vu, user_config_display, user_config_timer, user_config_tcs
from user_config_helpers import *
def readable(val):
val = [_[1] for c in val]
v = val[0]
if v == 0:
return 'Disabled'
if v < 16:
return 'ADC ' + str(v - 1)
if v < 32:
return 'GPI ' + str(v - 16)
if v < 88:
return 'Key ' + str(v - 32)
if v < 96:
return 'Rotary ' + str(v - 88)
if v < 112:
return 'AC In ' + str(v - 96)
if v < 128:
return 'Unused ' + str(v - 112)
if v == 128:
return 'Reserved'
if v == 129:
return 'Unused 129'
if v < 146:
return 'Output Configuration ' + str(v - 130)
if v == 146:
if val[1] == 0:
return 'Input Channels Show / Hide'
if val[1] == 4:
return 'Output Channels Show / Hide'
if v == 147:
return 'Unused 147'
if v < 152:
return 'Model Info ' + str(v - 148)
if v < 168:
return 'Input Audio Routing ' + str(v - 152)
if v < 184:
return 'Output Audio Routing ' + str(v - 168)
if v == 184:
return 'LED number ' + str(val[2])
if v == 185:
return 'FIR Flavour'
if v == 186:
return 'Network Configuration'
if v == 187:
return 'VU LED function ' + str(val[2])
if v == 188:
return 'VU LED bar ' + str(val[2])
if v == 189:
d = val[1] & 63
if d == 0:
return 'Q Configuration'
if d in (1, 2, 3):
return 'Stacking Configuration'
if d == 4:
return 'ADC and DAC Settings'
if d == 5:
return 'Display Selection'
return 'Undefined'
class CategoryPanel(wx.Panel):
def __init__(self, parent, frame, category, infotext='', group='', bg=None, size=(1000, 480), bgcolour=(220, 220, 220), fgcolour=(70, 70, 70)):
wx.Panel.__init__(self, parent, size=size)
self.parent = parent
self.frame = frame
self.categories = frame.categories
self.name = self.categories[category][1]
self.category = category
self.activePageNumber = 0
self.frame_height = 2 * wx.SystemSettings.GetMetric(wx.SYS_CAPTION_Y) + wx.SystemSettings.GetMetric(wx.SYS_BORDER_Y)
if os.name in mac_names:
self.frame_height = 24
self.SetSize((self.GetSize()[0], self.GetSize()[1] + self.frame_height))
self.p = wx.Panel(self)
self.p.SetSize((self.GetSize()[0], self.GetSize()[1] + self.frame_height))
self.p.SetPosition((0, 0))
print mytime.displayTime(), 'uc.creating category', category
self.uiPanels = {}
val = self.categories[category][0]
try:
sortedList = eval(self.frame.parent.config.get('DEFAULT', category + '_sort_order'))
except:
sortedList = sorted(val.keys())
if category in ('user_config_front_panel_keys', 'user_config_front_panel_leds',
'user_config_vu'):
print mytime.displayTime(), 'uc.CP.checking display configuration for', self.name
uiKeys = getKeys(self, 189)
primaryDisplay = 0
secondaryDisplay = 0
numberOfKeys = 0
for uiIndex in uiKeys:
(key, dVal) = uiKeys[uiIndex]
if dVal[1] == 5:
if numberOfKeys > 0:
self.frame.clear(self, 0, key=key)
continue
print mytime.displayTime(), ' -> key:', key, 'dVal', dVal
primaryDisplay = dVal[2] & 15
secondaryDisplay = dVal[3] & 15
print mytime.displayTime(), ' -> Primary Display:', primaryDisplay, user_config_display.primaryDisplayTypes[primaryDisplay]
print mytime.displayTime(), ' -> Secondary Display:', secondaryDisplay, user_config_display.secondaryDisplayTypes[secondaryDisplay]
numberOfKeys = 1
if primaryDisplay != 0:
if secondaryDisplay != 0 and user_config_display.secondaryDisplayTypes[secondaryDisplay] == 'XM' and user_config_display.primaryDisplayTypes[primaryDisplay] == 'D2':
cfgName = 'configurations/DPD2DSXM.cfg'
else:
cfgName = 'configurations/DP' + user_config_display.primaryDisplayTypes[primaryDisplay] + '.cfg'
print mytime.displayTime(), 'uc.reading config', cfgName
cfg = ConfigParser.ConfigParser()
cfg.read(cfgName)
if category == 'user_config_vu':
try:
self.frame.vuMeters = eval(cfg.get('DEFAULT', 'vuMeters'))
print mytime.displayTime(), 'uc.VU meters changed to:', self.frame.vuMeters
except:
pass
else:
try:
val = eval(self.frame.parent.config.get('DEFAULT', category))
print mytime.displayTime(), ' -> val 1:', val, 'for', category
try:
sortedList = eval(self.frame.parent.config.get('DEFAULT', category + '_sort_order'))
except:
sortedList = sorted(val.keys())
except:
try:
val = eval(cfg.get('DEFAULT', category))
print mytime.displayTime(), ' -> val 2:', val, 'for', category
try:
sortedList = eval(cfg.get('DEFAULT', category + '_sort_order'))
except:
sortedList = sorted(val.keys())
except:
print mytime.displayTime(), 'uc.error in display config for', user_config_display.primaryDisplayTypes[primaryDisplay]
traceback.print_exc(file=sys.stdout)
val = {}
sortedList = []
else:
print mytime.displayTime(), 'uc.sortedList changed to', sortedList
print mytime.displayTime(), 'uc.val changed to:', val
sortedList = list(sortedList)
if category == 'user_config_front_panel_keys':
for i in range(32):
if i + 32 not in val.keys():
val[i + 32] = str(i + 32) + ': Spare ' + str(i + 1)
sortedList.append(i + 32)
if category == 'user_config_gpi':
for i in range(8):
if i + 96 not in val.keys():
val[i + 96] = 'Clip ' + str(i + 1)
sortedList.append(i + 96)
for i in range(4):
if i + 96 + 8 not in val.keys():
val[i + 96 + 8] = 'Protect ' + str(i + 1)
sortedList.append(i + 96 + 8)
for i in range(4):
if i + 96 + 12 not in val.keys():
val[i + 96 + 12] = 'FB ' + str(i + 12)
sortedList.append(i + 96 + 12)
for i in range(16):
if i + 96 + 16 not in val.keys():
val[i + 96 + 16] = 'GPI ' + str(i)
sortedList.append(i + 96 + 16)
if category == 'user_config_front_panel_leds':
for i in range(32):
if i not in val.keys():
val[i] = 'Spare ' + str(i + 1)
sortedList.append(i)
sortedList = list(sortedList)
if len(val) > 10 and os.name in mac_names:
self.nb = wx.Choicebook(self.p, -1, pos=(0, 0))
self.nb.Bind(wx.EVT_CHOICEBOOK_PAGE_CHANGED, self.onTabChange)
self.nb.SetSize((936, 440))
else:
self.nb = wx.Notebook(self.p, pos=(0, 0))
self.nb.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.onTabChange)
self.nb.SetSize((946, 440))
for i in val.keys():
if i not in sortedList:
sortedList.append(i)
force = True
self.sortedListOfPanels = sortedList
try:
for uiNumber in sortedList:
panelName = val[uiNumber]
if panelName[0] == '_':
continue
self.uiPanels[uiNumber] = handlers[category](self.nb, self, uiNumber, panelName)
self.nb.AddPage(self.uiPanels[uiNumber], panelName)
self.uiPanels[uiNumber].initMe(force)
force = False
except:
print mytime.displayTime(), 'uc.error in sorted list', sortedList, val
traceback.print_exc(file=sys.stdout)
self.nb.Layout()
self.Show(True)
print mytime.displayTime() + ' Category', self.name, 'finished'
return
def initMe(self, force=False):
print mytime.displayTime(), 'uc.cp.initMe', self.name, len(self.uiPanels), 'panels'
self.Show(True)
force = True
for uiNumber in self.sortedListOfPanels:
page = self.uiPanels[uiNumber]
page.initMe(force)
page.Show(force)
force = False
return
def onTabChange(self, e):
pageNumber = e.Selection
self.changeTabTo(pageNumber)
e.StopPropagation()
e.Skip()
return
def changeTabTo(self, pageNumber):
self.activePageNumber = pageNumber
page = self.nb.GetPage(pageNumber)
print mytime.displayTime(), 'uc.cp.OnTabChange:: UI panel', self.name, 'to', page.name
page.initMe(force=True)
for otherPage in self.uiPanels.values():
if otherPage == page:
otherPage.Show(True)
else:
otherPage.Show(False)
return
class Dialog(wx.Dialog):
def __init__(self, parent, id, title, infotext='', group='', bg=None, size=(1000, 500), bgcolour=(220, 220, 220), fgcolour=(70, 70, 70), showCategories={}, panelName='all'):
wx.Dialog.__init__(self, None, wx.ID_ANY, title, size=size, style=wx.STAY_ON_TOP | wx.DEFAULT_DIALOG_STYLE)
self.parent = parent
self.title = title
self.panelName = panelName
self.showCategories = showCategories
self.getConfigParams()
self.activePageNumber = 0
self.frame_height = 2 * wx.SystemSettings.GetMetric(wx.SYS_CAPTION_Y) + wx.SystemSettings.GetMetric(wx.SYS_BORDER_Y)
if os.name in mac_names:
self.frame_height = 24
self.SetSize((self.GetSize()[0], self.GetSize()[1] + self.frame_height))
self.p = wx.Panel(self)
self.p.SetSize((self.GetSize()[0], self.GetSize()[1] + self.frame_height))
self.p.SetPosition((0, 0))
self.nb = wx.Notebook(self.p, pos=(20, 0))
self.nb.SetSize((960, 460))
self.buildPanels()
self.ok_button = wx.Button(self.p, 1, 'Apply', pos=(760, 470), size=(100, 20))
cancel_button = wx.Button(self.p, 2, 'Close', pos=(880, 470), size=(100, 20))
if one_unit.app.mijnpc == True:
save_button = wx.Button(self.p, 3, 'Save', pos=(20, 470), size=(70, 20))
clear_button = wx.Button(self.p, 4, 'Clear', pos=(110, 470), size=(70,
20))
load_button = wx.Button(self.p, 5, 'Load', pos=(200, 470), size=(70, 20))
self.Bind(wx.EVT_BUTTON, self.OnSave, id=3)
self.Bind(wx.EVT_BUTTON, self.OnClear, id=4)
self.Bind(wx.EVT_BUTTON, self.OnLoad, id=5)
self.Bind(wx.EVT_BUTTON, self.OnOK, id=1)
self.Bind(wx.EVT_BUTTON, self.OnCancel, id=2)
self.CenterOnScreen()
self.response = None
self.nb.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.onTabChange)
return
def buildPanels(self):
print mytime.displayTime() + ' uc.Building Panels...'
self.categoryPanels = {}
for category in self.showCategories:
(val, name) = self.categories[category]
try:
mylen = len(val)
except:
print mytime.displayTime(), 'uc.i.invalid type for category', category
continue
self.categoryPanels[category] = CategoryPanel(self.nb, self, category)
self.nb.AddPage(self.categoryPanels[category], name)
if os.name in mac_names:
self.categoryPanels[category].SetPosition((-3, -7))
else:
self.categoryPanels[category].SetPosition((-3, 20))
self.categoryPanels[category].SetSize((960, 430))
if self.parent.active_unit.MAC[:4] not in ('DEMO', 'VN::', 'GRP_') and self.parent.model.completion() < 100:
progressDial = wx.ProgressDialog('One moment please....', 'Collecting Panels...')
progressDial.SetSize((300, 110))
progressDial.Update(50, 'Building Panels...')
progressDial.Update(80, 'Fetching Data...')
self.parent.waitForSync('uc.init')
progressDial.Destroy()
print mytime.displayTime() + ' uc.Building Panels Done'
return
def refreshPanels(self):
print mytime.displayTime(), 'uc.rP: ja dit werkt nog niet, later naar kijken. Notebook delete en add etc niet vergeten.'
return
def getConfigParams(self):
self.categories = {}
for category in self.showCategories:
if category == 'user_config_a_enabled_channels':
val = {146: 'Show / Hide Channels'}
elif category == 'user_config_dc_in':
val = {}
for i in range(12):
val[i + 1] = 'DC input ' + str(i + 1)
elif category == 'user_config_display_selection':
val = {189: 'Display Selection'}
elif category == 'user_config_audio_routing':
res = {}
for channel in self.parent.unit_channels:
if channel == 0:
res[channel + 152] = 'Input ' + str(channel + 1)
elif channel == 128:
res[channel + 40] = getString('op') + ' ' + str(channel - 127)
elif channel > 128:
res[channel + 40] = str(channel - 127)
elif channel < 128:
res[channel + 152] = str(channel + 1)
val = res
elif category == 'user_config_az_output_configuration':
res = {}
for channel in self.parent.unit_channels:
if channel >= 128:
try:
channelNameKey = data_model.Key(protocol.STRUCT_ID_CHANNEL, protocol.MEMBER_ID_SHORT_NAME, channel, 0)
channelName = self.parent.model.get(channelNameKey).strip()
if channelName.strip() == '':
channelName = getString('op') + ' ' + str(channel - 127)
res[channel + 2] = channelName
except:
res[channel + 2] = getString('op') + ' ' + str(channel - 127)
val = res
elif category == 'tcsLevel':
res = {}
res[131] = 'Level 1'
res[132] = 'Level 2'
res[133] = 'Turbo'
val = res
elif category == 'user_config_model_definition':
val = {148: 'DSP', 149: 'DSP Assembly', 150: 'Amplifier Assembly', 151: 'End Product', 191: 'Reserved 1'}
elif category == 'user_config_network':
val = {186: 'Network'}
elif category == 'user_config_vu':
val = {187: 'VU LED functions', 188: 'VU meters'}
try:
self.vuMeters = eval(self.parent.config.get('DEFAULT', 'vuMeters'))
except:
self.vuMeters = {}
for i in range(32):
self.vuMeters[i] = 'VU meter ' + str(i + 1)
else:
if category == 'user_config_various':
try:
val = eval(self.parent.config.get('DEFAULT', 'user_config_FIR'))
except:
val = {}
else:
val['189a'] = 'Various 1'
val['189b'] = 'Various 2'
val['189i'] = 'Various 3'
val['189c'] = 'Reserved 1'
val['189d'] = 'Reserved 2'
val['189e'] = 'Reserved 3'
val['189f'] = 'Latency'
val['189g'] = 'Fan Control'
val['189h'] = 'Limits and Calibration'
elif category == 'timer':
val = {'190a': 'Page 1', '190b': 'Page 2', '190c': 'Page 3'}
else:
try:
val = eval(self.parent.config.get('DEFAULT', category))
except:
val = {}
try:
name = eval(self.parent.config.get('DEFAULT', category + '_name'))
except:
name = getString(categoryNames[category])
self.categories[category] = (
val, name)
return
def onTabChange(self, e):
pageNumber = e.Selection
self.changeTabTo(pageNumber)
e.Skip()
return
def changeTabTo(self, pageNumber):
self.activePageNumber = pageNumber
page = self.nb.GetPage(pageNumber)
print mytime.displayTime(), 'uc.d.OnTabChange:: Category Panel', page.name
page.initMe(force=True)
for otherPage in self.categoryPanels.values():
if otherPage == page:
otherPage.Show(True)
otherPage.changeTabTo(otherPage.activePageNumber)
else:
otherPage.Show(False)
return
def getKeys(self, initAll=False):
keySet = {}
for panelName in self.categoryPanels.keys():
panel = self.categoryPanels[panelName]
if panelName == 'user_config_audio':
continue
if initAll:
panel.initMe(force=True)
for subPanelName in panel.uiPanels.keys():
subPanel = panel.uiPanels[subPanelName]
if hasattr(subPanel, 'subPanels'):
subPanels = subPanel.subPanels.values()
else:
subPanels = [
subPanel]
fkWissen = None
for subPanel in subPanels:
if initAll:
subPanel.initMe(force=True)
for lineNumber in subPanel.lines:
line = subPanel.lines[lineNumber]
try:
if line.key.channel == 1 and line.key.index >= 128:
continue
except:
pass
try:
res = subPanel.evaluateLine(line)
except:
print mytime.displayTime() + ' uc.oo.Failed to evaluate line', panelName, subPanelName, lineNumber
traceback.print_exc(file=sys.stdout)
dlgMessage = 'Line ' + str(int(lineNumber) + 1) + ' in ' + panel.name + ' for ' + subPanel.name + ' contains illegal data. This line will be ignored.'
dlgTitle = 'Warning'
res = wx.MessageBox(dlgMessage, dlgTitle, wx.OK)
continue
if res != None:
key = line.key
if key == None:
freeUIslot = findFreeUI(self.parent, keySet)
if freeUIslot == None:
if self.parent.active_unit.MAC.startswith('DEMO') == True:
freeUIslot = 0
else:
print mytime.displayTime(), 'uc.oo.No more free UI slots!'
continue
key = data_model.Key(protocol.STRUCT_ID_UI_CONTROL, protocol.MEMBER_ID_UI_CONTROL, freeUIslot / 256, freeUIslot % 256)
line.key = key
keySet[key] = res
else:
key = line.key
if key == None:
continue
print mytime.displayTime(), 'uc.oo.deactivating key:', key, 'value', self.parent.model.get(key)
res = '' + chr(0)
res += chr(0)
res += chr(0)
res += chr(0)
res += chr(0)
res += chr(0)
res += chr(0)
res += chr(0)
keySet[key] = res
return keySet
def OnOK(self, evt):
self.executeOK()
return
def executeOK(self):
self.response = 'OK'
self.ok_button.SetLabel('Applying...')
keySet = self.getKeys()
for key in keySet:
self.parent.set_value(key, keySet[key])
self.parent.refreshUIControls()
one_unit.tryYield()
mytime.sleep(0.5)
for key in keySet:
self.parent.waitForSync('uc.oO.exit', key=key)
self.ok_button.SetLabel('Apply')
return
def OnCancel(self, evt):
self.response = 'Close'
if self.IsModal == False:
self.Destroy()
else:
self.Close()
return
def OnSave(self, e):
self.save('all', initAll=True)
return
def save(self, scope, filename='UI keys for', initAll=False):
keySet = self.getKeys(initAll)
if scope == 'all':
f = open(filename + ' ' + self.panelName + '.csv', 'wb')
f.write('s|m|c|i|v0|v1|v2|v3|v4|v5|v6|v7|uf|category|description' + '\n')
for key in keySet:
line = protocol.csvString(key)
val = keySet[key]
if val[0] == 0:
continue
for v in val:
line += '|' + str(ord(v))
if key.channel == 1 and key.num >= 128:
continue
else:
line = line + '|User'
line = line + '|' + readable(val)
f.write(line + '\n')
f.close()
return
def OnLoad(self, e):
self.load()
self.refreshAll()
return
def load(self, path=None):
if path == None:
dlg = wx.FileDialog(self, message='Choose a UI file', defaultDir='', defaultFile='', wildcard='UI File (*.csv)|*.csv', style=wx.OPEN | wx.CHANGE_DIR)
if dlg.ShowModal() == wx.ID_OK:
path = dlg.GetPath()
dlg.Destroy()
if path:
f = open(path, 'rb')
data = f.readlines()
f.close()
for line in data:
arr = line.split('|')
try:
a = [_[1] for a in arr[:12]]
key = data_model.Key(a[0], a[1], a[2], a[3])
val = ''
for c in a[4:12]:
val += chr(c)
freeUIslot = findFreeUI(self.parent, {})
if freeUIslot == None:
if self.parent.active_unit.MAC.startswith('DEMO') == True:
freeUIslot = 0
else:
print mytime.displayTime(), 'uc.oo.No more free UI slots!'
continue
key = data_model.Key(protocol.STRUCT_ID_UI_CONTROL, protocol.MEMBER_ID_UI_CONTROL, freeUIslot / 256, freeUIslot % 256)
print mytime.displayTime(), 'setting ui key:', key, 'to', a[4:12]
self.parent.set_value(key, val)
except:
continue
return
def refreshAll(self):
self.refreshPanels()
self.response = 'OK'
self.ok_button.SetLabel('Applying...')
keySet = self.getKeys()
self.parent.refreshUIControls()
one_unit.tryYield()
mytime.sleep(2)
for key in keySet:
self.parent.waitForSync('uc.oO.exit', key=key)
self.ok_button.SetLabel('Apply')
wx.CallAfter(self.parent.restoreUserConfigurationPanel, self.title, self.showCategories, self.panelName)
if self.IsModal == False:
self.Destroy()
else:
self.Close()
return
def OnClear(self, e):
print mytime.displayTime(), 'uc.oc.1'
dlgMessage = 'All keys will be cleared. Continue?'
dlgTitle = 'Clear User Keys'
res = wx.MessageBox(dlgMessage, dlgTitle, wx.OK | wx.CANCEL)
if res != wx.OK:
return
self.clear(self, 'all')
self.refreshAll()
return
def clear(self, parent, uiNumber, memberID=None, structID=None, key=None):
print mytime.displayTime(), 'uc.c.1', uiNumber, memberID, structID
if key != None:
if key.channel == 1 and key.num == 128:
return
print mytime.displayTime(), 'uc.c.Clearing', key
res = '' + chr(0)
res += chr(0)
res += chr(0)
res += chr(0)
res += chr(0)
res += chr(0)
res += chr(0)
res += chr(0)
self.parent.set_value(key, res)
elif uiNumber == 'all':
keySet = self.getKeys()
for key in keySet:
if key.channel == 1 and key.num == 128:
continue
print mytime.displayTime(), 'uc.c.Clearing', key,
print [_[1] for c in keySet[key]]
res = '' + chr(0)
res += chr(0)
res += chr(0)
res += chr(0)
res += chr(0)
res += chr(0)
res += chr(0)
res += chr(0)
self.parent.set_value(key, res)
else:
keySet = getKeys(parent, uiNumber, memberID=memberID, structID=structID)
print mytime.displayTime(), 'uc.c.keySet:', keySet
for index in keySet.keys():
key = keySet[index][0]
if key.channel == 1 and key.num == 128:
continue
print mytime.displayTime(), 'uc.c.Clearing', key, keySet[index][1]
res = '' + chr(0)
res += chr(0)
res += chr(0)
res += chr(0)
res += chr(0)
res += chr(0)
res += chr(0)
res += chr(0)
self.parent.set_value(key, res)
return
handlers = {'user_config_a_enabled_channels': (user_config_audio.enableChannels),
'user_config_audio_routing': (user_config_audio.audioRouting),
'user_config_az_output_configuration': (user_config_audio.outputConfiguration),
'tcsLevel': (user_config_tcs.outputConfiguration),
'user_config_dc_in': (user_config_dc.ADC_input),
'user_config_gpi': (user_config_keys.frontPanelKeys),
'user_config_front_panel_keys': (user_config_keys.frontPanelKeys),
'user_config_front_panel_leds': (user_config_leds.frontPanelLeds),
'user_config_various': (user_config_various.FIR),
'user_config_model_definition': (user_config_model.modelConfiguration),
'user_config_network': (user_config_network.networkConfiguration),
'user_config_vu': (user_config_vu.vuMeterSelectPanel),
'user_config_display_selection': (user_config_display.displayConfiguration),
'timer': (user_config_timer.setTimer)}
categoryNames = {'user_config_a_enabled_channels': 'uccc',
'user_config_audio_routing': 'ucar',
'user_config_az_output_configuration': 'ucoc',
'user_config_dc_in': 'ucdi',
'user_config_gpi': 'ucgpi',
'user_config_front_panel_keys': 'uck',
'user_config_front_panel_leds': 'ucl',
'user_config_vu': 'ucv',
'user_config_various': 'ucgs',
'user_config_model_definition': 'ucps',
'user_config_network': 'ucn',
'user_config_display_selection': 'ucds',
'timer': 'ucst',
'tcsLevel': 'ucoc'}
# okay decompiling pycode/user_config.pyc