fix: correct cache key format to match .env file structure

The root cause of config overwrites was key mismatch:
- .env file uses: ERP_URL, DB_TYPE, DB_NAME (underscore uppercase)
- Code was using: erp.url, database.dbType (dot notation)

Fixed in three methods:
- saveAllSettings() - now sets cache with correct keys
- resetToDefaults() - now uses correct keys
- save() - now reads cache with correct keys

This ensures partial save preserves unmodified fields.
This commit is contained in:
Misaka_Company
2026-03-03 15:42:40 +08:00
parent 73a49f9de3
commit 816060444c

View File

@@ -256,21 +256,21 @@ export class ConfigManager {
lines.push('# ===========================') lines.push('# ===========================')
lines.push('# ERP 系统配置') lines.push('# ERP 系统配置')
lines.push('# ===========================') lines.push('# ===========================')
lines.push(`ERP_URL=${this.configCache.get('erp.url') || DEFAULT_SETTINGS.erp.url}`) lines.push(`ERP_URL=${this.configCache.get('ERP_URL') || DEFAULT_SETTINGS.erp.url}`)
lines.push( lines.push(
`ERP_USERNAME=${this.configCache.get('erp.username') || DEFAULT_SETTINGS.erp.username}` `ERP_USERNAME=${this.configCache.get('ERP_USERNAME') || DEFAULT_SETTINGS.erp.username}`
) )
lines.push( lines.push(
`ERP_PASSWORD=${this.configCache.get('erp.password') || DEFAULT_SETTINGS.erp.password}` `ERP_PASSWORD=${this.configCache.get('ERP_PASSWORD') || DEFAULT_SETTINGS.erp.password}`
) )
lines.push( lines.push(
`ERP_HEADLESS=${this.configCache.get('erp.headless') || DEFAULT_SETTINGS.erp.headless}` `ERP_HEADLESS=${this.configCache.get('ERP_HEADLESS') || DEFAULT_SETTINGS.erp.headless}`
) )
lines.push( lines.push(
`ERP_IGNORE_HTTPS_ERRORS=${this.configCache.get('erp.ignoreHttpsErrors') || DEFAULT_SETTINGS.erp.ignoreHttpsErrors}` `ERP_IGNORE_HTTPS_ERRORS=${this.configCache.get('ERP_IGNORE_HTTPS_ERRORS') || DEFAULT_SETTINGS.erp.ignoreHttpsErrors}`
) )
lines.push( lines.push(
`ERP_AUTO_CLOSE_BROWSER=${this.configCache.get('erp.autoCloseBrowser') || DEFAULT_SETTINGS.erp.autoCloseBrowser}` `ERP_AUTO_CLOSE_BROWSER=${this.configCache.get('ERP_AUTO_CLOSE_BROWSER') || DEFAULT_SETTINGS.erp.autoCloseBrowser}`
) )
lines.push('') lines.push('')
@@ -279,10 +279,10 @@ export class ConfigManager {
lines.push('# 数据库配置 - SQL Server') lines.push('# 数据库配置 - SQL Server')
lines.push('# ===========================') lines.push('# ===========================')
lines.push(`# DB_TYPE=sqlserver`) lines.push(`# DB_TYPE=sqlserver`)
lines.push(`# DB_SERVER=${this.configCache.get('database.server') || ''}`) lines.push(`# DB_SERVER=${this.configCache.get('DB_SERVER') || ''}`)
lines.push(`# DB_NAME=${this.configCache.get('database.database') || ''}`) lines.push(`# DB_NAME=${this.configCache.get('DB_NAME') || ''}`)
lines.push(`# DB_USERNAME=${this.configCache.get('database.username') || ''}`) lines.push(`# DB_USERNAME=${this.configCache.get('DB_USERNAME') || ''}`)
lines.push(`# DB_PASSWORD=${this.configCache.get('database.password') || ''}`) lines.push(`# DB_PASSWORD=${this.configCache.get('DB_PASSWORD') || ''}`)
lines.push(`DB_SQLSERVER_DRIVER=ODBC Driver 18 for SQL Server`) lines.push(`DB_SQLSERVER_DRIVER=ODBC Driver 18 for SQL Server`)
lines.push(`DB_TRUST_SERVER_CERTIFICATE=yes`) lines.push(`DB_TRUST_SERVER_CERTIFICATE=yes`)
lines.push('') lines.push('')
@@ -292,22 +292,22 @@ export class ConfigManager {
lines.push('# 数据库配置 - MySQL (切换时使用)') lines.push('# 数据库配置 - MySQL (切换时使用)')
lines.push('# ===========================') lines.push('# ===========================')
lines.push( lines.push(
`DB_TYPE=${this.configCache.get('database.dbType') || DEFAULT_SETTINGS.database.dbType}` `DB_TYPE=${this.configCache.get('DB_TYPE') || DEFAULT_SETTINGS.database.dbType}`
) )
lines.push( lines.push(
`DB_NAME=${this.configCache.get('database.database') || DEFAULT_SETTINGS.database.database}` `DB_NAME=${this.configCache.get('DB_NAME') || DEFAULT_SETTINGS.database.database}`
) )
lines.push( lines.push(
`DB_USERNAME=${this.configCache.get('database.username') || DEFAULT_SETTINGS.database.username}` `DB_USERNAME=${this.configCache.get('DB_USERNAME') || DEFAULT_SETTINGS.database.username}`
) )
lines.push( lines.push(
`DB_PASSWORD=${this.configCache.get('database.password') || DEFAULT_SETTINGS.database.password}` `DB_PASSWORD=${this.configCache.get('DB_PASSWORD') || DEFAULT_SETTINGS.database.password}`
) )
lines.push( lines.push(
`DB_MYSQL_HOST=${this.configCache.get('database.mysqlHost') || DEFAULT_SETTINGS.database.mysqlHost}` `DB_MYSQL_HOST=${this.configCache.get('DB_MYSQL_HOST') || DEFAULT_SETTINGS.database.mysqlHost}`
) )
lines.push( lines.push(
`DB_MYSQL_PORT=${this.configCache.get('database.mysqlPort') || DEFAULT_SETTINGS.database.mysqlPort}` `DB_MYSQL_PORT=${this.configCache.get('DB_MYSQL_PORT') || DEFAULT_SETTINGS.database.mysqlPort}`
) )
lines.push(`DB_MYSQL_CHARSET=utf8mb4`) lines.push(`DB_MYSQL_CHARSET=utf8mb4`)
lines.push('') lines.push('')
@@ -327,14 +327,14 @@ export class ConfigManager {
lines.push('# 路径配置') lines.push('# 路径配置')
lines.push('# ===========================') lines.push('# ===========================')
lines.push( lines.push(
`PATH_DATA_DIR=${this.configCache.get('paths.dataDir') || DEFAULT_SETTINGS.paths.dataDir}` `PATH_DATA_DIR=${this.configCache.get('PATH_DATA_DIR') || DEFAULT_SETTINGS.paths.dataDir}`
) )
lines.push(`PATH_PRODUCTION_ID_FILE=ProductionID.txt`) lines.push(`PATH_PRODUCTION_ID_FILE=ProductionID.txt`)
lines.push( lines.push(
`PATH_DEFAULT_OUTPUT=${this.configCache.get('paths.defaultOutput') || DEFAULT_SETTINGS.paths.defaultOutput}` `PATH_DEFAULT_OUTPUT=${this.configCache.get('PATH_DEFAULT_OUTPUT') || DEFAULT_SETTINGS.paths.defaultOutput}`
) )
lines.push( lines.push(
`PATH_VALIDATION_OUTPUT=${this.configCache.get('paths.validationOutput') || DEFAULT_SETTINGS.paths.validationOutput}` `PATH_VALIDATION_OUTPUT=${this.configCache.get('PATH_VALIDATION_OUTPUT') || DEFAULT_SETTINGS.paths.validationOutput}`
) )
lines.push('') lines.push('')
@@ -343,19 +343,19 @@ export class ConfigManager {
lines.push('# 数据提取配置') lines.push('# 数据提取配置')
lines.push('# ===========================') lines.push('# ===========================')
lines.push( lines.push(
`EXTRACTION_BATCH_SIZE=${this.configCache.get('extraction.batchSize') || DEFAULT_SETTINGS.extraction.batchSize}` `EXTRACTION_BATCH_SIZE=${this.configCache.get('EXTRACTION_BATCH_SIZE') || DEFAULT_SETTINGS.extraction.batchSize}`
) )
lines.push( lines.push(
`EXTRACTION_VERBOSE=${this.configCache.get('extraction.verbose') || DEFAULT_SETTINGS.extraction.verbose}` `EXTRACTION_VERBOSE=${this.configCache.get('EXTRACTION_VERBOSE') || DEFAULT_SETTINGS.extraction.verbose}`
) )
lines.push( lines.push(
`EXTRACTION_AUTO_CONVERT=${this.configCache.get('extraction.autoConvert') || DEFAULT_SETTINGS.extraction.autoConvert}` `EXTRACTION_AUTO_CONVERT=${this.configCache.get('EXTRACTION_AUTO_CONVERT') || DEFAULT_SETTINGS.extraction.autoConvert}`
) )
lines.push( lines.push(
`EXTRACTION_MERGE_BATCHES=${this.configCache.get('extraction.mergeBatches') || DEFAULT_SETTINGS.extraction.mergeBatches}` `EXTRACTION_MERGE_BATCHES=${this.configCache.get('EXTRACTION_MERGE_BATCHES') || DEFAULT_SETTINGS.extraction.mergeBatches}`
) )
lines.push( lines.push(
`EXTRACTION_ENABLE_DB_PERSISTENCE=${this.configCache.get('extraction.enableDbPersistence') || DEFAULT_SETTINGS.extraction.enableDbPersistence}` `EXTRACTION_ENABLE_DB_PERSISTENCE=${this.configCache.get('EXTRACTION_ENABLE_DB_PERSISTENCE') || DEFAULT_SETTINGS.extraction.enableDbPersistence}`
) )
lines.push('') lines.push('')
@@ -364,22 +364,22 @@ export class ConfigManager {
lines.push('# 校验配置') lines.push('# 校验配置')
lines.push('# ===========================') lines.push('# ===========================')
lines.push( lines.push(
`VALIDATION_DATA_SOURCE=${this.configCache.get('validation.dataSource') || DEFAULT_SETTINGS.validation.dataSource}` `VALIDATION_DATA_SOURCE=${this.configCache.get('VALIDATION_DATA_SOURCE') || DEFAULT_SETTINGS.validation.dataSource}`
) )
lines.push( lines.push(
`VALIDATION_USE_DATABASE=${this.configCache.get('validation.useDatabase') || true}` `VALIDATION_USE_DATABASE=${this.configCache.get('VALIDATION_USE_DATABASE') || true}`
) )
lines.push( lines.push(
`VALIDATION_BATCH_SIZE=${this.configCache.get('validation.batchSize') || DEFAULT_SETTINGS.validation.batchSize}` `VALIDATION_BATCH_SIZE=${this.configCache.get('VALIDATION_BATCH_SIZE') || DEFAULT_SETTINGS.validation.batchSize}`
) )
lines.push( lines.push(
`VALIDATION_ENABLE_CRUD=${this.configCache.get('validation.enableCrud') || DEFAULT_SETTINGS.validation.enableCrud}` `VALIDATION_ENABLE_CRUD=${this.configCache.get('VALIDATION_ENABLE_CRUD') || DEFAULT_SETTINGS.validation.enableCrud}`
) )
lines.push( lines.push(
`VALIDATION_DEFAULT_MANAGER=${this.configCache.get('validation.defaultManager') || DEFAULT_SETTINGS.validation.defaultManager}` `VALIDATION_DEFAULT_MANAGER=${this.configCache.get('VALIDATION_DEFAULT_MANAGER') || DEFAULT_SETTINGS.validation.defaultManager}`
) )
lines.push( lines.push(
`VALIDATION_MATCH_MODE=${this.configCache.get('validation.matchMode') || DEFAULT_SETTINGS.validation.matchMode}` `VALIDATION_MATCH_MODE=${this.configCache.get('VALIDATION_MATCH_MODE') || DEFAULT_SETTINGS.validation.matchMode}`
) )
lines.push('') lines.push('')
@@ -388,13 +388,13 @@ export class ConfigManager {
lines.push('# UI 配置') lines.push('# UI 配置')
lines.push('# ===========================') lines.push('# ===========================')
lines.push( lines.push(
`UI_FONT_FAMILY=${this.configCache.get('ui.fontFamily') || DEFAULT_SETTINGS.ui.fontFamily}` `UI_FONT_FAMILY=${this.configCache.get('UI_FONT_FAMILY') || DEFAULT_SETTINGS.ui.fontFamily}`
) )
lines.push( lines.push(
`UI_FONT_SIZE=${this.configCache.get('ui.fontSize') || DEFAULT_SETTINGS.ui.fontSize}` `UI_FONT_SIZE=${this.configCache.get('UI_FONT_SIZE') || DEFAULT_SETTINGS.ui.fontSize}`
) )
lines.push( lines.push(
`UI_PRODUCTION_ID_INPUT_WIDTH=${this.configCache.get('ui.productionIdInputWidth') || DEFAULT_SETTINGS.ui.productionIdInputWidth}` `UI_PRODUCTION_ID_INPUT_WIDTH=${this.configCache.get('UI_PRODUCTION_ID_INPUT_WIDTH') || DEFAULT_SETTINGS.ui.productionIdInputWidth}`
) )
lines.push('') lines.push('')
@@ -403,7 +403,7 @@ export class ConfigManager {
lines.push('# 执行配置') lines.push('# 执行配置')
lines.push('# ===========================') lines.push('# ===========================')
lines.push( lines.push(
`EXECUTION_DRYRUN=${this.configCache.get('execution.dryRun') || DEFAULT_SETTINGS.execution.dryRun}` `EXECUTION_DRYRUN=${this.configCache.get('EXECUTION_DRYRUN') || DEFAULT_SETTINGS.execution.dryRun}`
) )
const content = lines.join('\n') const content = lines.join('\n')
@@ -506,49 +506,49 @@ export class ConfigManager {
* Save settings from SettingsData object * Save settings from SettingsData object
*/ */
public async saveAllSettings(settings: SettingsData): Promise<boolean> { public async saveAllSettings(settings: SettingsData): Promise<boolean> {
// ERP settings // ERP settings - use underscore uppercase keys to match .env file
this.set('erp.url', settings.erp.url) this.set('ERP_URL', settings.erp.url)
this.set('erp.username', settings.erp.username) this.set('ERP_USERNAME', settings.erp.username)
this.set('erp.password', settings.erp.password) this.set('ERP_PASSWORD', settings.erp.password)
this.set('erp.headless', settings.erp.headless) this.set('ERP_HEADLESS', settings.erp.headless)
this.set('erp.ignoreHttpsErrors', settings.erp.ignoreHttpsErrors) this.set('ERP_IGNORE_HTTPS_ERRORS', settings.erp.ignoreHttpsErrors)
this.set('erp.autoCloseBrowser', settings.erp.autoCloseBrowser) this.set('ERP_AUTO_CLOSE_BROWSER', settings.erp.autoCloseBrowser)
// Database settings // Database settings
this.set('database.dbType', settings.database.dbType) this.set('DB_TYPE', settings.database.dbType)
this.set('database.server', settings.database.server) this.set('DB_SERVER', settings.database.server)
this.set('database.mysqlHost', settings.database.mysqlHost) this.set('DB_MYSQL_HOST', settings.database.mysqlHost)
this.set('database.mysqlPort', settings.database.mysqlPort) this.set('DB_MYSQL_PORT', settings.database.mysqlPort)
this.set('database.database', settings.database.database) this.set('DB_NAME', settings.database.database)
this.set('database.username', settings.database.username) this.set('DB_USERNAME', settings.database.username)
this.set('database.password', settings.database.password) this.set('DB_PASSWORD', settings.database.password)
// Path settings // Path settings
this.set('paths.dataDir', settings.paths.dataDir) this.set('PATH_DATA_DIR', settings.paths.dataDir)
this.set('paths.defaultOutput', settings.paths.defaultOutput) this.set('PATH_DEFAULT_OUTPUT', settings.paths.defaultOutput)
this.set('paths.validationOutput', settings.paths.validationOutput) this.set('PATH_VALIDATION_OUTPUT', settings.paths.validationOutput)
// Extraction settings // Extraction settings
this.set('extraction.batchSize', settings.extraction.batchSize) this.set('EXTRACTION_BATCH_SIZE', settings.extraction.batchSize)
this.set('extraction.verbose', settings.extraction.verbose) this.set('EXTRACTION_VERBOSE', settings.extraction.verbose)
this.set('extraction.autoConvert', settings.extraction.autoConvert) this.set('EXTRACTION_AUTO_CONVERT', settings.extraction.autoConvert)
this.set('extraction.mergeBatches', settings.extraction.mergeBatches) this.set('EXTRACTION_MERGE_BATCHES', settings.extraction.mergeBatches)
this.set('extraction.enableDbPersistence', settings.extraction.enableDbPersistence) this.set('EXTRACTION_ENABLE_DB_PERSISTENCE', settings.extraction.enableDbPersistence)
// Validation settings // Validation settings
this.set('validation.dataSource', settings.validation.dataSource) this.set('VALIDATION_DATA_SOURCE', settings.validation.dataSource)
this.set('validation.batchSize', settings.validation.batchSize) this.set('VALIDATION_BATCH_SIZE', settings.validation.batchSize)
this.set('validation.matchMode', settings.validation.matchMode) this.set('VALIDATION_MATCH_MODE', settings.validation.matchMode)
this.set('validation.enableCrud', settings.validation.enableCrud) this.set('VALIDATION_ENABLE_CRUD', settings.validation.enableCrud)
this.set('validation.defaultManager', settings.validation.defaultManager) this.set('VALIDATION_DEFAULT_MANAGER', settings.validation.defaultManager)
// UI settings // UI settings
this.set('ui.fontFamily', settings.ui.fontFamily) this.set('UI_FONT_FAMILY', settings.ui.fontFamily)
this.set('ui.fontSize', settings.ui.fontSize) this.set('UI_FONT_SIZE', settings.ui.fontSize)
this.set('ui.productionIdInputWidth', settings.ui.productionIdInputWidth) this.set('UI_PRODUCTION_ID_INPUT_WIDTH', settings.ui.productionIdInputWidth)
// Execution settings // Execution settings
this.set('execution.dryRun', settings.execution.dryRun) this.set('EXECUTION_DRYRUN', settings.execution.dryRun)
return this.save() return this.save()
} }
@@ -573,10 +573,12 @@ export class ConfigManager {
} }
} }
// Step 2: Read current settings // Step 2: Read current settings from .env file directly
// This avoids the cache key mismatch issue (ERP_URL vs erp.url)
await this.loadEnvFile()
const currentSettings = this.getAllSettings() const currentSettings = this.getAllSettings()
// Step 3: Deep merge // Step 3: Deep merge - only update provided fields
const mergedSettings = deepMerge(currentSettings, settings) const mergedSettings = deepMerge(currentSettings, settings)
// Step 4: Backup and save // Step 4: Backup and save
@@ -622,43 +624,43 @@ export class ConfigManager {
// Clear cache and reload from defaults // Clear cache and reload from defaults
this.configCache.clear() this.configCache.clear()
// Set all defaults // Set all defaults using underscore uppercase keys
this.set('erp.url', DEFAULT_SETTINGS.erp.url) this.set('ERP_URL', DEFAULT_SETTINGS.erp.url)
this.set('erp.username', DEFAULT_SETTINGS.erp.username) this.set('ERP_USERNAME', DEFAULT_SETTINGS.erp.username)
this.set('erp.password', DEFAULT_SETTINGS.erp.password) this.set('ERP_PASSWORD', DEFAULT_SETTINGS.erp.password)
this.set('erp.headless', DEFAULT_SETTINGS.erp.headless) this.set('ERP_HEADLESS', DEFAULT_SETTINGS.erp.headless)
this.set('erp.ignoreHttpsErrors', DEFAULT_SETTINGS.erp.ignoreHttpsErrors) this.set('ERP_IGNORE_HTTPS_ERRORS', DEFAULT_SETTINGS.erp.ignoreHttpsErrors)
this.set('erp.autoCloseBrowser', DEFAULT_SETTINGS.erp.autoCloseBrowser) this.set('ERP_AUTO_CLOSE_BROWSER', DEFAULT_SETTINGS.erp.autoCloseBrowser)
this.set('database.dbType', DEFAULT_SETTINGS.database.dbType) this.set('DB_TYPE', DEFAULT_SETTINGS.database.dbType)
this.set('database.server', DEFAULT_SETTINGS.database.server) this.set('DB_SERVER', DEFAULT_SETTINGS.database.server)
this.set('database.mysqlHost', DEFAULT_SETTINGS.database.mysqlHost) this.set('DB_MYSQL_HOST', DEFAULT_SETTINGS.database.mysqlHost)
this.set('database.mysqlPort', DEFAULT_SETTINGS.database.mysqlPort) this.set('DB_MYSQL_PORT', DEFAULT_SETTINGS.database.mysqlPort)
this.set('database.database', DEFAULT_SETTINGS.database.database) this.set('DB_NAME', DEFAULT_SETTINGS.database.database)
this.set('database.username', DEFAULT_SETTINGS.database.username) this.set('DB_USERNAME', DEFAULT_SETTINGS.database.username)
this.set('database.password', DEFAULT_SETTINGS.database.password) this.set('DB_PASSWORD', DEFAULT_SETTINGS.database.password)
this.set('paths.dataDir', DEFAULT_SETTINGS.paths.dataDir) this.set('PATH_DATA_DIR', DEFAULT_SETTINGS.paths.dataDir)
this.set('paths.defaultOutput', DEFAULT_SETTINGS.paths.defaultOutput) this.set('PATH_DEFAULT_OUTPUT', DEFAULT_SETTINGS.paths.defaultOutput)
this.set('paths.validationOutput', DEFAULT_SETTINGS.paths.validationOutput) this.set('PATH_VALIDATION_OUTPUT', DEFAULT_SETTINGS.paths.validationOutput)
this.set('extraction.batchSize', DEFAULT_SETTINGS.extraction.batchSize) this.set('EXTRACTION_BATCH_SIZE', DEFAULT_SETTINGS.extraction.batchSize)
this.set('extraction.verbose', DEFAULT_SETTINGS.extraction.verbose) this.set('EXTRACTION_VERBOSE', DEFAULT_SETTINGS.extraction.verbose)
this.set('extraction.autoConvert', DEFAULT_SETTINGS.extraction.autoConvert) this.set('EXTRACTION_AUTO_CONVERT', DEFAULT_SETTINGS.extraction.autoConvert)
this.set('extraction.mergeBatches', DEFAULT_SETTINGS.extraction.mergeBatches) this.set('EXTRACTION_MERGE_BATCHES', DEFAULT_SETTINGS.extraction.mergeBatches)
this.set('extraction.enableDbPersistence', DEFAULT_SETTINGS.extraction.enableDbPersistence) this.set('EXTRACTION_ENABLE_DB_PERSISTENCE', DEFAULT_SETTINGS.extraction.enableDbPersistence)
this.set('validation.dataSource', DEFAULT_SETTINGS.validation.dataSource) this.set('VALIDATION_DATA_SOURCE', DEFAULT_SETTINGS.validation.dataSource)
this.set('validation.batchSize', DEFAULT_SETTINGS.validation.batchSize) this.set('VALIDATION_BATCH_SIZE', DEFAULT_SETTINGS.validation.batchSize)
this.set('validation.matchMode', DEFAULT_SETTINGS.validation.matchMode) this.set('VALIDATION_MATCH_MODE', DEFAULT_SETTINGS.validation.matchMode)
this.set('validation.enableCrud', DEFAULT_SETTINGS.validation.enableCrud) this.set('VALIDATION_ENABLE_CRUD', DEFAULT_SETTINGS.validation.enableCrud)
this.set('validation.defaultManager', DEFAULT_SETTINGS.validation.defaultManager) this.set('VALIDATION_DEFAULT_MANAGER', DEFAULT_SETTINGS.validation.defaultManager)
this.set('ui.fontFamily', DEFAULT_SETTINGS.ui.fontFamily) this.set('UI_FONT_FAMILY', DEFAULT_SETTINGS.ui.fontFamily)
this.set('ui.fontSize', DEFAULT_SETTINGS.ui.fontSize) this.set('UI_FONT_SIZE', DEFAULT_SETTINGS.ui.fontSize)
this.set('ui.productionIdInputWidth', DEFAULT_SETTINGS.ui.productionIdInputWidth) this.set('UI_PRODUCTION_ID_INPUT_WIDTH', DEFAULT_SETTINGS.ui.productionIdInputWidth)
this.set('execution.dryRun', DEFAULT_SETTINGS.execution.dryRun) this.set('EXECUTION_DRYRUN', DEFAULT_SETTINGS.execution.dryRun)
return DEFAULT_SETTINGS return DEFAULT_SETTINGS
} }