Major update and bugfixes
Changelog:
This commit is contained in:
+6
-1
@@ -164,5 +164,10 @@ black.py
|
||||
test.py
|
||||
dsk/cookies.json
|
||||
|
||||
# Development and testing this app
|
||||
/templates/diff copy.html
|
||||
/mods
|
||||
/mods
|
||||
/backups
|
||||
/backups_debug
|
||||
new_keys.bak
|
||||
newKeys_ru_ru copy.json
|
||||
@@ -15,7 +15,7 @@ app = Flask(__name__)
|
||||
jsonUtils = Utils()
|
||||
translationHelper = TranslationHelper(deepseekApiToken=os.getenv("DEEPSEEK_API_TOKEN"), yandexApiType="ios")
|
||||
|
||||
TRANSLATION_PROMPT = """You are a master Russian translator specializing in creative adaptations.
|
||||
OLD_TRANSLATION_PROMPT = """You are a master Russian translator specializing in creative adaptations.
|
||||
For each English phrase, provide exactly 10 Russian translations showing different approaches:
|
||||
|
||||
1. Literal translation
|
||||
@@ -35,6 +35,34 @@ Format strictly as:
|
||||
...
|
||||
10. Translation 10
|
||||
|
||||
Never include explanations or additional text.
|
||||
"""
|
||||
NEW_TRANSLATION_PROMPT = """You are a master Russian translator specializing in creative adaptations.
|
||||
For each English phrase, provide exactly 10 Russian translations showing different approaches.
|
||||
First must contain little Easter egg based on russian films, games, etc.. but others - no.
|
||||
|
||||
Format strictly as:
|
||||
1. Translation 1
|
||||
2. Translation 2
|
||||
...
|
||||
10. Translation 10
|
||||
|
||||
Never include explanations or additional text.
|
||||
"""
|
||||
LEARNING_TRANSLATION_PROMPT = """You are a master Russian translator specializing in creative adaptations for Minecraft mods. Currently you are translating Oritech mod for Minecraft 1.21.1.
|
||||
I pasted json with my translations before this message for u to see how translation is already done and what words you should use. If some line in this json contains "//TODO" or "//REDO" or is a whitespace ignore it.
|
||||
For each English phrase, provide exactly 10 Russian translations showing different approaches.
|
||||
If you are asked to translate a phrase that is already translated in json i provided, try to make something more simmilar to it and save different accent phrases from it also include one exact same translation as in the json file.
|
||||
One of translations must be little Easter egg based on russian films, games, etc... Second translation must be in Humorous twist (if appropriate) approach.
|
||||
Also you must strictly use already translated name for items or blocks if they appear in phrase that i am asking you to translate. Double check conjugation and declension in russian words!
|
||||
If English phrase is whitespace or empty string ignore it and return one translation: "[Failed] Check text you sent to me.".
|
||||
|
||||
Format strictly as:
|
||||
1. Translation 1
|
||||
2. Translation 2
|
||||
...
|
||||
10. Translation 10
|
||||
|
||||
Never include explanations or additional text.
|
||||
"""
|
||||
|
||||
@@ -61,7 +89,28 @@ def get_ai_suggestions():
|
||||
return jsonify({'error': 'No text provided'}), 400
|
||||
|
||||
try:
|
||||
suggestions = translationHelper.getDeepseekTranslation(text, prompt=TRANSLATION_PROMPT)
|
||||
suggestions = translationHelper.getDeepseekTranslation(text, prompt=NEW_TRANSLATION_PROMPT)
|
||||
|
||||
return jsonify({
|
||||
'suggestions': suggestions
|
||||
})
|
||||
except Exception as e:
|
||||
return jsonify({
|
||||
'error': str(e),
|
||||
'suggestions': []
|
||||
})
|
||||
|
||||
@app.route('/get_learning_ai_suggestions', methods=['POST', "GET"])
|
||||
def get_learning_ai_suggestions():
|
||||
text = request.json.get('text', '')
|
||||
if not text:
|
||||
return jsonify({'error': 'No text provided'}), 400
|
||||
|
||||
try:
|
||||
translations = jsonUtils.get_existing_translations()
|
||||
new_prompt = str(translations) + "\n" + LEARNING_TRANSLATION_PROMPT
|
||||
# print(new_prompt)
|
||||
suggestions = translationHelper.getDeepseekTranslation(text, prompt=new_prompt)
|
||||
|
||||
return jsonify({
|
||||
'suggestions': suggestions
|
||||
@@ -115,6 +164,12 @@ def show_differences():
|
||||
'common': comparison['key_diff']['common']
|
||||
}
|
||||
|
||||
# Filter TODO/REDO items
|
||||
todo_items = []
|
||||
for item in key_differences['added']:
|
||||
if isinstance(item['value'], str) and ('//TODO' in item['value'].upper() or '//REDO' in item['value'].upper()):
|
||||
todo_items.append(item)
|
||||
|
||||
# Load existing translations (both original and new, already sorted)
|
||||
existing_translations = jsonUtils.get_existing_translations()
|
||||
|
||||
@@ -123,7 +178,8 @@ def show_differences():
|
||||
key_differences=key_differences,
|
||||
ru_file=ru_file,
|
||||
en_file=en_file,
|
||||
existing_translations=existing_translations)
|
||||
existing_translations=existing_translations,
|
||||
todo_items=todo_items)
|
||||
|
||||
except Exception as e:
|
||||
return render_template('error.html', error=str(e))
|
||||
@@ -141,5 +197,23 @@ def save_translations():
|
||||
except Exception as e:
|
||||
return jsonify({'status': 'error', 'message': str(e)}), 500
|
||||
|
||||
@app.route('/save_todo_translations', methods=['POST'])
|
||||
def save_todo_translations():
|
||||
translations = request.json
|
||||
|
||||
if not translations:
|
||||
return jsonify({'status': 'error', 'message': 'No translations provided'}), 400
|
||||
|
||||
try:
|
||||
# Load existing translations
|
||||
existing_translations = jsonUtils.load_json('newKeys_ru_ru.json')
|
||||
# Update with new translations
|
||||
existing_translations.update(translations)
|
||||
# Save back to file
|
||||
jsonUtils.save_json('newKeys_ru_ru.json', existing_translations)
|
||||
return jsonify({'status': 'success', 'saved': len(translations)})
|
||||
except Exception as e:
|
||||
return jsonify({'status': 'error', 'message': str(e)}), 500
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run()
|
||||
+344
-332
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"advancements.oritech.augmenter": "Кибернетика!",
|
||||
"advancements.oritech.augmenter.description": "Преодолейте свои естественные… лимиты! Предупреждение: Может вызвать повышенное желание говорить «бип-буп».",
|
||||
"advancements.oritech.augmenter": "Киберимпланты!",
|
||||
"advancements.oritech.augmenter.description": "Преодолейте свои естественные… лимиты! Внимание: Может вызвать повышенное желание взорвать Арасака-тауэр.",
|
||||
"advancements.oritech.reactor": "Ядерная энергетика",
|
||||
"advancements.oritech.reactor.description": "Собери реактор. Безопасность? Не, не слышал... Ой, смотри, как красиво светится!",
|
||||
"block.oritech.advanced_augment_station": [
|
||||
{
|
||||
"text": "Квантовая исследовательская станция",
|
||||
"text": "Станция квантовых исследований",
|
||||
"color": "#40f5ef"
|
||||
}
|
||||
],
|
||||
@@ -20,336 +20,348 @@
|
||||
"block.oritech.carbon_plating_pressure_plate": "Нажимная плита из усиленной карбоном обшивки",
|
||||
"block.oritech.carbon_plating_slab": "Плита из усиленной карбоном обшивки",
|
||||
"block.oritech.carbon_plating_stairs": "Ступеньки из усиленной карбоном обшивки",
|
||||
"block.oritech.machine_core_hidden": "",
|
||||
"block.oritech.machine_silk_touch_addon": "",
|
||||
"block.oritech.refinery_block": "",
|
||||
"block.oritech.refinery_module_block": "",
|
||||
"block.oritech.simple_augment_station": "",
|
||||
"block.oritech.still_biofuel_block": "",
|
||||
"block.oritech.still_molten_adamant_block": "",
|
||||
"block.oritech.still_molten_biosteel_block": "",
|
||||
"block.oritech.still_molten_duratium_block": "",
|
||||
"block.oritech.still_molten_energite_block": "",
|
||||
"block.oritech.still_molten_fluxite": "",
|
||||
"block.oritech.transparent_item_pipe": "",
|
||||
"block.oritech.unstable_container": "",
|
||||
"emi.category.oritech.refinery": "",
|
||||
"fluid.oritech.still_biofuel": "",
|
||||
"fluid.oritech.still_diesel": "",
|
||||
"fluid.oritech.still_heavy_oil": "",
|
||||
"fluid.oritech.still_mineral_slurry": "",
|
||||
"fluid.oritech.still_molten_adamant": "",
|
||||
"fluid.oritech.still_molten_biosteel": "",
|
||||
"fluid.oritech.still_molten_duratium": "",
|
||||
"fluid.oritech.still_molten_energite": "",
|
||||
"fluid.oritech.still_molten_fluxite": "",
|
||||
"fluid.oritech.still_naphtha": "",
|
||||
"fluid.oritech.still_sheol_fire": "",
|
||||
"fluid.oritech.still_silicon_wash": "",
|
||||
"fluid.oritech.still_strange_matter": "",
|
||||
"fluid.oritech.still_sulfuric_acid": "",
|
||||
"item.oritech.clay_catalyst_beads": "",
|
||||
"item.oritech.electric_mace": "",
|
||||
"item.oritech.ion_thruster": "",
|
||||
"item.oritech.portable_laser": "",
|
||||
"item.oritech.reinforced_carbon_sheet": "",
|
||||
"item.oritech.still_biofuel_bucket": "",
|
||||
"item.oritech.still_diesel_bucket": "",
|
||||
"item.oritech.still_heavy_oil_bucket": "",
|
||||
"item.oritech.still_mineral_slurry_bucket": "",
|
||||
"item.oritech.still_molten_adamant_bucket": "",
|
||||
"item.oritech.still_molten_biosteel_bucket": "",
|
||||
"item.oritech.still_molten_duratium_bucket": "",
|
||||
"item.oritech.still_molten_energite_bucket": "",
|
||||
"item.oritech.still_molten_fluxite_bucket": "",
|
||||
"item.oritech.still_naphtha_bucket": "",
|
||||
"item.oritech.still_sheol_fire_bucket": "",
|
||||
"item.oritech.still_silicon_wash_bucket": "",
|
||||
"item.oritech.still_strange_matter_bucket": "",
|
||||
"item.oritech.still_sulfuric_acid_bucket": "",
|
||||
"item.oritech.unstable_container": "",
|
||||
"key.oritech.augment_screen": "",
|
||||
"message.oritech.steamengine.controller_link": "",
|
||||
"oracle_index.title.oritech": "",
|
||||
"oritech.text.augment.armor": "",
|
||||
"oritech.text.augment.armor.desc": "",
|
||||
"oritech.text.augment.armor.desc.1": "",
|
||||
"oritech.text.augment.attackdamage": "",
|
||||
"oritech.text.augment.attackdamage.desc": "фпвыфпв",
|
||||
"oritech.text.augment.attackdamage.desc.1": "",
|
||||
"oritech.text.augment.autofeeder": "",
|
||||
"oritech.text.augment.autofeeder.desc": "",
|
||||
"oritech.text.augment.autofeeder.desc.1": "",
|
||||
"oritech.text.augment.autofeeder.desc.2": "",
|
||||
"oritech.text.augment.betterarmor": "",
|
||||
"oritech.text.augment.betterarmor.desc": "",
|
||||
"oritech.text.augment.betterarmor.desc.1": "",
|
||||
"oritech.text.augment.blockreach": "",
|
||||
"oritech.text.augment.blockreach.desc": "",
|
||||
"oritech.text.augment.blockreach.desc.1": "",
|
||||
"oritech.text.augment.cloak": "",
|
||||
"oritech.text.augment.cloak.desc": "",
|
||||
"oritech.text.augment.cloak.desc.1": "",
|
||||
"oritech.text.augment.cloak.desc.3": "",
|
||||
"oritech.text.augment.dwarf": "",
|
||||
"oritech.text.augment.dwarf.desc": "",
|
||||
"oritech.text.augment.dwarf.desc.1": "",
|
||||
"oritech.text.augment.dwarf.desc.2": "",
|
||||
"oritech.text.augment.farblockreach": "",
|
||||
"oritech.text.augment.farblockreach.desc": "",
|
||||
"oritech.text.augment.farblockreach.desc.1": "",
|
||||
"oritech.text.augment.farblockreach.desc.2": "",
|
||||
"oritech.text.augment.flight": "",
|
||||
"oritech.text.augment.flight.desc": "",
|
||||
"oritech.text.augment.flight.desc.1": "",
|
||||
"oritech.text.augment.giant": "",
|
||||
"oritech.text.augment.giant.desc": "",
|
||||
"oritech.text.augment.giant.desc.1": "",
|
||||
"oritech.text.augment.giant.desc.2": "",
|
||||
"oritech.text.augment.gravity": "",
|
||||
"oritech.text.augment.gravity.desc": "",
|
||||
"oritech.text.augment.gravity.desc.1": "",
|
||||
"oritech.text.augment.hpboost": "",
|
||||
"oritech.text.augment.hpboost.desc": "",
|
||||
"oritech.text.augment.hpboost.desc.1": "",
|
||||
"oritech.text.augment.hpboostmore": "",
|
||||
"oritech.text.augment.hpboostmore.desc": "",
|
||||
"oritech.text.augment.hpboostmore.desc.1": "",
|
||||
"oritech.text.augment.hpboostultimate": "",
|
||||
"oritech.text.augment.hpboostultimate.desc": "",
|
||||
"oritech.text.augment.hpboostultimate.desc.1": "",
|
||||
"oritech.text.augment.hpboostultra": "",
|
||||
"oritech.text.augment.hpboostultra.desc": "фыа",
|
||||
"oritech.text.augment.hpboostultra.desc.1": "",
|
||||
"oritech.text.augment.luck": "",
|
||||
"oritech.text.augment.luck.desc": "",
|
||||
"oritech.text.augment.luck.desc.1": "",
|
||||
"oritech.text.augment.luck.desc.2": "",
|
||||
"oritech.text.augment.magnet": "",
|
||||
"oritech.text.augment.magnet.desc": "",
|
||||
"oritech.text.augment.magnet.desc.1": "",
|
||||
"oritech.text.augment.magnet.desc.2": "",
|
||||
"oritech.text.augment.miningspeed": "",
|
||||
"oritech.text.augment.miningspeed.desc": "",
|
||||
"oritech.text.augment.miningspeed.desc.1": "",
|
||||
"oritech.text.augment.nightvision": "",
|
||||
"oritech.text.augment.nightvision.desc": "",
|
||||
"oritech.text.augment.nightvision.desc.1": "",
|
||||
"oritech.text.augment.nightvision.desc.2": "",
|
||||
"oritech.text.augment.orefinder": "",
|
||||
"oritech.text.augment.orefinder.desc": "",
|
||||
"oritech.text.augment.orefinder.desc.1": "",
|
||||
"oritech.text.augment.orefinder.desc.2": "",
|
||||
"oritech.text.augment.portal": "",
|
||||
"oritech.text.augment.portal.desc": "",
|
||||
"oritech.text.augment.portal.desc.1": "",
|
||||
"oritech.text.augment.speedboost": "",
|
||||
"oritech.text.augment.speedboost.desc": "",
|
||||
"oritech.text.augment.speedboost.desc.1": "",
|
||||
"oritech.text.augment.stepassist": "",
|
||||
"oritech.text.augment.stepassist.desc": "",
|
||||
"oritech.text.augment.stepassist.desc.1": "",
|
||||
"oritech.text.augment.stepassist.desc.2": "",
|
||||
"oritech.text.augment.superattackdamage": "",
|
||||
"oritech.text.augment.superattackdamage.desc": "",
|
||||
"oritech.text.augment.superattackdamage.desc.1": "фвып",
|
||||
"oritech.text.augment.superminingspeed": "",
|
||||
"oritech.text.augment.superminingspeed.desc": "",
|
||||
"oritech.text.augment.superminingspeed.desc.1": "",
|
||||
"oritech.text.augment.superminingspeed.desc.2": "",
|
||||
"oritech.text.augment.superspeedboost": "",
|
||||
"oritech.text.augment.superspeedboost.desc": "",
|
||||
"oritech.text.augment.superspeedboost.desc.1": "",
|
||||
"oritech.text.augment.superspeedboost.desc.2": "",
|
||||
"oritech.text.augment.ultimatearmor": "",
|
||||
"oritech.text.augment.ultimatearmor.desc": "",
|
||||
"oritech.text.augment.ultimatearmor.desc.1": "",
|
||||
"oritech.text.augment.waterbreath": "",
|
||||
"oritech.text.augment.waterbreath.desc": "",
|
||||
"oritech.text.augment.waterbreath.desc.1": "",
|
||||
"oritech.text.augment.weaponreach": "",
|
||||
"oritech.text.augment.weaponreach.desc": "",
|
||||
"oritech.text.augment.weaponreach.desc.1": "",
|
||||
"oritech.text.augment_ingredient_tip": "",
|
||||
"oritech.text.augment_op.apply": "",
|
||||
"oritech.text.augment_op.pending": "",
|
||||
"oritech.text.augment_op.remove": "",
|
||||
"oritech.text.augment_op.research": "",
|
||||
"oritech.text.augment_research_time": "",
|
||||
"oritech.text.augment_resource_cost": "",
|
||||
"oritech.text.augment_toggle": "",
|
||||
"oritech.text.energy_cost": "",
|
||||
"oritech.text.missing_requirements_title": "",
|
||||
"oritech.text.required_station": "",
|
||||
"rei.process.oritech:refinery": "",
|
||||
"tag.item.c.bananas": "",
|
||||
"tag.item.c.biodiesel": "",
|
||||
"tag.item.c.clumps": "",
|
||||
"tag.item.c.clumps.copper": "",
|
||||
"tag.item.c.clumps.gold": "",
|
||||
"tag.item.c.clumps.iron": "",
|
||||
"tag.item.c.clumps.nickel": "",
|
||||
"tag.item.c.clumps.platinum": "",
|
||||
"tag.item.c.dusts.plutonium": "",
|
||||
"tag.item.c.dusts.uranium": "",
|
||||
"tag.item.c.fuels.bio": "",
|
||||
"tag.item.c.fuels.block.bio": "",
|
||||
"tag.item.c.high_power_biodiesel": "",
|
||||
"tag.item.c.oil": "",
|
||||
"tag.item.c.ores.uranium": "",
|
||||
"tag.item.c.plastics": "",
|
||||
"tag.item.c.raw_materials.nickel": "",
|
||||
"tag.item.c.raw_materials.platinum": "",
|
||||
"tag.item.c.raw_materials.uranium": "",
|
||||
"tag.item.c.steam": "",
|
||||
"tag.item.c.tools.wrench": "",
|
||||
"tag.item.oritech.biofuel": "",
|
||||
"tag.item.oritech.biomatter": "",
|
||||
"tag.item.oritech.reactor_coolant_items": "",
|
||||
"tag.item.oritech.recyclable.biomass": "",
|
||||
"tag.item.oritech.recyclable.copper_dust": "",
|
||||
"tag.item.oritech.recyclable.diamond": "",
|
||||
"tag.item.oritech.recyclable.gold_dust": "",
|
||||
"tag.item.oritech.recyclable.gravel": "dsag",
|
||||
"tag.item.oritech.recyclable.iron_dust": "",
|
||||
"tag.item.oritech.recyclable.netherite_scrap": "",
|
||||
"tag.item.oritech.recyclable.quartz_dust_2": "",
|
||||
"tag.item.oritech.recyclable.quartz_dust_4": "",
|
||||
"tag.item.oritech.recyclable.red_sand": "",
|
||||
"tag.item.oritech.recyclable.redstone_dust": "",
|
||||
"tag.item.oritech.recyclable.sand": "",
|
||||
"tag.item.oritech.recyclable.small_copper_dust": "",
|
||||
"tag.item.oritech.recyclable.small_gold_dust": "",
|
||||
"tag.item.oritech.recyclable.small_iron_dust": "",
|
||||
"tag.item.oritech.recyclable.string": "",
|
||||
"tag.item.oritech.turbofuel": "",
|
||||
"text.config.oritech-config.category.addonConfig": "",
|
||||
"text.config.oritech-config.category.electricMace": "",
|
||||
"text.config.oritech-config.category.portableLaserConfig": "",
|
||||
"text.config.oritech-config.category.processingMachines.refineryData": "",
|
||||
"text.config.oritech-config.option.acceleratorMotorRFCapacity": "",
|
||||
"text.config.oritech-config.option.additiveAddons": "",
|
||||
"text.config.oritech-config.option.additiveAddons.tooltip": "",
|
||||
"text.config.oritech-config.option.addonConfig.chamberAddonEfficiency": "",
|
||||
"text.config.oritech-config.option.addonConfig.efficiencyAddonEfficiency": "",
|
||||
"text.config.oritech-config.option.addonConfig.speedAddonEfficiency": "",
|
||||
"text.config.oritech-config.option.addonConfig.speedAddonSpeed": "",
|
||||
"text.config.oritech-config.option.addonConfig.ultimateAddonEfficiency": "",
|
||||
"text.config.oritech-config.option.addonConfig.ultimateAddonSpeed": "",
|
||||
"text.config.oritech-config.option.augmenterMaxEnergy": "",
|
||||
"text.config.oritech-config.option.boringNukes": "",
|
||||
"text.config.oritech-config.option.catalystHyperExpFactor": "",
|
||||
"text.config.oritech-config.option.catalystHyperExpFactor.tooltip": "",
|
||||
"text.config.oritech-config.option.chainsawTreeCutting": "",
|
||||
"text.config.oritech-config.option.electricMace.baseDamage": "",
|
||||
"text.config.oritech-config.option.electricMace.chargeSpeed": "",
|
||||
"text.config.oritech-config.option.electricMace.energyCapacity": "",
|
||||
"text.config.oritech-config.option.electricMace.energyUsage": "",
|
||||
"text.config.oritech-config.option.electricMace.lightningCostMultiplier": "",
|
||||
"text.config.oritech-config.option.enableHelpButton": "",
|
||||
"text.config.oritech-config.option.generateOresFabricOnly": "",
|
||||
"text.config.oritech-config.option.generateOresFabricOnly.tooltip": "",
|
||||
"text.config.oritech-config.option.generators.steamEngineData.rfToSteamRatio": "",
|
||||
"text.config.oritech-config.option.generators.steamEngineData.rfToSteamRatio.tooltip": "",
|
||||
"text.config.oritech-config.option.generators.steamEngineData.steamToRfRatio": "",
|
||||
"text.config.oritech-config.option.generators.steamEngineData.stopOnEnergyFull": "",
|
||||
"text.config.oritech-config.option.generators.steamEngineData.stopOnEnergyFull.tooltip": "",
|
||||
"text.config.oritech-config.option.generators.steamEngineData.stopOnWaterFull": "",
|
||||
"text.config.oritech-config.option.generators.steamEngineData.stopOnWaterFull.tooltip": "",
|
||||
"text.config.oritech-config.option.generators.steamId": "",
|
||||
"text.config.oritech-config.option.generators.steamId.tooltip": "",
|
||||
"text.config.oritech-config.option.layeredExtenders": "",
|
||||
"text.config.oritech-config.option.layeredExtenders.tooltip": "",
|
||||
"text.config.oritech-config.option.portableLaserConfig.blockBreakSpeed": "",
|
||||
"text.config.oritech-config.option.portableLaserConfig.damageBase": "",
|
||||
"text.config.oritech-config.option.portableLaserConfig.energyCapacity": "",
|
||||
"text.config.oritech-config.option.portableLaserConfig.energyPerBoom": "",
|
||||
"text.config.oritech-config.option.portableLaserConfig.energyPerTick": "",
|
||||
"text.config.oritech-config.option.portableLaserConfig.explosionStrength": "фывфыв",
|
||||
"text.config.oritech-config.option.processingMachines.refineryData.energyCapacity": "",
|
||||
"text.config.oritech-config.option.processingMachines.refineryData.energyPerTick": "",
|
||||
"text.config.oritech-config.option.processingMachines.refineryData.maxEnergyExtraction": "",
|
||||
"text.config.oritech-config.option.processingMachines.refineryData.maxEnergyInsertion": "",
|
||||
"text.config.oritech-config.option.reactorMaxEnergyOutput": "",
|
||||
"text.config.oritech-config.option.reactorMaxEnergyStored": "",
|
||||
"text.config.oritech-config.option.showMachinePreview": "",
|
||||
"text.config.oritech-config.option.unstableContainerBaseCapacity": "",
|
||||
"text.config.oritech-config.section.augments": "",
|
||||
"text.oritech.augmenter_active": "",
|
||||
"text.oritech.augmenter_creative_tooltip": "",
|
||||
"text.oritech.begin_research": "",
|
||||
"text.oritech.cancel": "",
|
||||
"text.oritech.install": "",
|
||||
"text.oritech.load_augments.tooltip": "",
|
||||
"text.oritech.loaded_augments": "",
|
||||
"block.oritech.machine_core_hidden": "Цельная обшивка",
|
||||
"block.oritech.machine_silk_touch_addon": "Модуль: Шелковое касание",
|
||||
"block.oritech.refinery_block": "Очистительный завод",
|
||||
"block.oritech.refinery_module_block": "Модуль: Перегонный куб",
|
||||
"block.oritech.simple_augment_station": "Станция изучения кибернетики",
|
||||
"block.oritech.still_biofuel_block": "Биотопливо",
|
||||
"block.oritech.still_molten_adamant_block": "Расплавленный адамантит",
|
||||
"block.oritech.still_molten_biosteel_block": "Расплавленная биосталь",
|
||||
"block.oritech.still_molten_duratium_block": "Расплавленный дюратий",
|
||||
"block.oritech.still_molten_energite_block": "Расплавленный энергит",
|
||||
"block.oritech.still_molten_fluxite": "Расплавленный флюксит",
|
||||
"block.oritech.transparent_item_pipe": "Прозрачная предметная труба",
|
||||
"block.oritech.unstable_container": "Сейф Шредингера",
|
||||
"emi.category.oritech.refinery": "Очистка",
|
||||
"fluid.oritech.still_biofuel": "Биотопливо",
|
||||
"fluid.oritech.still_diesel": "Дизель",
|
||||
"fluid.oritech.still_heavy_oil": "Тяжелая нефть",
|
||||
"fluid.oritech.still_mineral_slurry": "Минеральный шлак",
|
||||
"fluid.oritech.still_molten_adamant": "Расплавленный адамантит",
|
||||
"fluid.oritech.still_molten_biosteel": "Расплавленная биосталь",
|
||||
"fluid.oritech.still_molten_duratium": "Расплавленный дюратий",
|
||||
"fluid.oritech.still_molten_energite": "Расплавленный энергит",
|
||||
"fluid.oritech.still_molten_fluxite": "Расплавленный флюксит",
|
||||
"fluid.oritech.still_naphtha": "Лёгкая нафта",
|
||||
"fluid.oritech.still_sheol_fire": "Шеольский огонь",
|
||||
"fluid.oritech.still_silicon_wash": "Кремниевый раствор",
|
||||
"fluid.oritech.still_strange_matter": "Странная материя",
|
||||
"fluid.oritech.still_sulfuric_acid": "Серная кислота",
|
||||
"item.oritech.clay_catalyst_beads": "Катализатор из гранулированной глины",
|
||||
"item.oritech.electric_mace": "Электрическая булава",
|
||||
"item.oritech.ion_thruster": "Ионный двигатель",
|
||||
"item.oritech.portable_laser": [
|
||||
{
|
||||
"text": "Эндеритовый рельсотрон",
|
||||
"color": "#ffd505"
|
||||
}
|
||||
],
|
||||
"item.oritech.reinforced_carbon_sheet": "Углепластик",
|
||||
"item.oritech.still_biofuel_bucket": "Ведро биотоплива",
|
||||
"item.oritech.still_diesel_bucket": "Ведро дизеля",
|
||||
"item.oritech.still_heavy_oil_bucket": "Ведро тяжёлой нефти",
|
||||
"item.oritech.still_mineral_slurry_bucket": "Ведро минерального шлака",
|
||||
"item.oritech.still_molten_adamant_bucket": "Ведро расплавленного адамантита",
|
||||
"item.oritech.still_molten_biosteel_bucket": "Ведро расплавленной биостали",
|
||||
"item.oritech.still_molten_duratium_bucket": "Ведро расплавленного дюратия",
|
||||
"item.oritech.still_molten_energite_bucket": "Ведро расплавленного энергита",
|
||||
"item.oritech.still_molten_fluxite_bucket": "Ведро расплавленного флюксита",
|
||||
"item.oritech.still_naphtha_bucket": "Ведро лёгкой нафты",
|
||||
"item.oritech.still_sheol_fire_bucket": "Ведро шеольского пламени",
|
||||
"item.oritech.still_silicon_wash_bucket": "Ведро кремниевого раствора",
|
||||
"item.oritech.still_strange_matter_bucket": "Ведро странной материи",
|
||||
"item.oritech.still_sulfuric_acid_bucket": "Ведро серной кислоты",
|
||||
"item.oritech.unstable_container": "Сейф Шредингера",
|
||||
"key.oritech.augment_screen": "(Удерживайте) Элементы управления имплантатами [Oritech]//TODO",
|
||||
"message.oritech.steamengine.controller_link": "Паровой двигатель соединен с основным двигателем (см. выделенный блок). Используйте только основной двигатель.",
|
||||
"oracle_index.title.oritech": "Oritech",
|
||||
"oritech.text.augment.armor": "ХУЙ //TODO",
|
||||
"oritech.text.augment.armor.desc": "//TODO",
|
||||
"oritech.text.augment.armor.desc.1": "//TODO",
|
||||
"oritech.text.augment.attackdamage": "//TODO",
|
||||
"oritech.text.augment.attackdamage.desc": "//TODO",
|
||||
"oritech.text.augment.attackdamage.desc.1": "//TODO",
|
||||
"oritech.text.augment.autofeeder": "//TODO",
|
||||
"oritech.text.augment.autofeeder.desc": "//TODO",
|
||||
"oritech.text.augment.autofeeder.desc.1": "//TODO",
|
||||
"oritech.text.augment.autofeeder.desc.2": "//TODO",
|
||||
"oritech.text.augment.betterarmor": "//TODO",
|
||||
"oritech.text.augment.betterarmor.desc": "//TODO",
|
||||
"oritech.text.augment.betterarmor.desc.1": "//TODO",
|
||||
"oritech.text.augment.blockreach": "//TODO",
|
||||
"oritech.text.augment.blockreach.desc": "//TODO",
|
||||
"oritech.text.augment.blockreach.desc.1": "//TODO",
|
||||
"oritech.text.augment.cloak": "Плащ",
|
||||
"oritech.text.augment.cloak.desc": "//TODO",
|
||||
"oritech.text.augment.cloak.desc.1": "//TODO",
|
||||
"oritech.text.augment.cloak.desc.3": "//TODO",
|
||||
"oritech.text.augment.dwarf": "//TODO",
|
||||
"oritech.text.augment.dwarf.desc": "//TODO",
|
||||
"oritech.text.augment.dwarf.desc.1": "//TODO",
|
||||
"oritech.text.augment.dwarf.desc.2": "//TODO",
|
||||
"oritech.text.augment.farblockreach": "//TODO",
|
||||
"oritech.text.augment.farblockreach.desc": "//TODO",
|
||||
"oritech.text.augment.farblockreach.desc.1": "//TODO",
|
||||
"oritech.text.augment.farblockreach.desc.2": "//TODO",
|
||||
"oritech.text.augment.flight": "Полёт",
|
||||
"oritech.text.augment.flight.desc": "//TODO",
|
||||
"oritech.text.augment.flight.desc.1": "//TODO",
|
||||
"oritech.text.augment.giant": "Гигантизм",
|
||||
"oritech.text.augment.giant.desc": "//TODO",
|
||||
"oritech.text.augment.giant.desc.1": "//TODO",
|
||||
"oritech.text.augment.giant.desc.2": "//TODO",
|
||||
"oritech.text.augment.gravity": "//TODO",
|
||||
"oritech.text.augment.gravity.desc": "//TODO",
|
||||
"oritech.text.augment.gravity.desc.1": "//TODO",
|
||||
"oritech.text.augment.hpboost": "//TODO",
|
||||
"oritech.text.augment.hpboost.desc": "//TODO",
|
||||
"oritech.text.augment.hpboost.desc.1": "//TODO",
|
||||
"oritech.text.augment.hpboostmore": "//TODO",
|
||||
"oritech.text.augment.hpboostmore.desc": "//TODO",
|
||||
"oritech.text.augment.hpboostmore.desc.1": "//TODO",
|
||||
"oritech.text.augment.hpboostultimate": "//TODO",
|
||||
"oritech.text.augment.hpboostultimate.desc": "//TODO",
|
||||
"oritech.text.augment.hpboostultimate.desc.1": "//TODO",
|
||||
"oritech.text.augment.hpboostultra": "//TODO",
|
||||
"oritech.text.augment.hpboostultra.desc": "//TODO",
|
||||
"oritech.text.augment.hpboostultra.desc.1": "//TODO",
|
||||
"oritech.text.augment.luck": "Удача",
|
||||
"oritech.text.augment.luck.desc": "//TODO",
|
||||
"oritech.text.augment.luck.desc.1": "//TODO",
|
||||
"oritech.text.augment.luck.desc.2": "//TODO",
|
||||
"oritech.text.augment.magnet": "Магнит",
|
||||
"oritech.text.augment.magnet.desc": "//TODO",
|
||||
"oritech.text.augment.magnet.desc.1": "//TODO",
|
||||
"oritech.text.augment.magnet.desc.2": "//TODO",
|
||||
"oritech.text.augment.miningspeed": "//TODO",
|
||||
"oritech.text.augment.miningspeed.desc": "//TODO",
|
||||
"oritech.text.augment.miningspeed.desc.1": "//TODO",
|
||||
"oritech.text.augment.nightvision": "Ночное зрение",
|
||||
"oritech.text.augment.nightvision.desc": "//TODO",
|
||||
"oritech.text.augment.nightvision.desc.1": "//TODO",
|
||||
"oritech.text.augment.nightvision.desc.2": "//TODO",
|
||||
"oritech.text.augment.orefinder": "//TODO",
|
||||
"oritech.text.augment.orefinder.desc": "//TODO",
|
||||
"oritech.text.augment.orefinder.desc.1": "//TODO",
|
||||
"oritech.text.augment.orefinder.desc.2": "//TODO",
|
||||
"oritech.text.augment.portal": "//TODO",
|
||||
"oritech.text.augment.portal.desc": "//TODO",
|
||||
"oritech.text.augment.portal.desc.1": "//TODO",
|
||||
"oritech.text.augment.speedboost": "//TODO",
|
||||
"oritech.text.augment.speedboost.desc": "//TODO",
|
||||
"oritech.text.augment.speedboost.desc.1": "//TODO",
|
||||
"oritech.text.augment.stepassist": "//TODO",
|
||||
"oritech.text.augment.stepassist.desc": "//TODO",
|
||||
"oritech.text.augment.stepassist.desc.1": "//TODO",
|
||||
"oritech.text.augment.stepassist.desc.2": "//TODO",
|
||||
"oritech.text.augment.superattackdamage": "//TODO",
|
||||
"oritech.text.augment.superattackdamage.desc": "//TODO",
|
||||
"oritech.text.augment.superattackdamage.desc.1": "//TODO",
|
||||
"oritech.text.augment.superminingspeed": "//TODO",
|
||||
"oritech.text.augment.superminingspeed.desc": "//TODO",
|
||||
"oritech.text.augment.superminingspeed.desc.1": "//TODO",
|
||||
"oritech.text.augment.superminingspeed.desc.2": "//TODO",
|
||||
"oritech.text.augment.superspeedboost": "//TODO",
|
||||
"oritech.text.augment.superspeedboost.desc": "//TODO",
|
||||
"oritech.text.augment.superspeedboost.desc.1": "//TODO",
|
||||
"oritech.text.augment.superspeedboost.desc.2": "//TODO",
|
||||
"oritech.text.augment.ultimatearmor": "//TODO",
|
||||
"oritech.text.augment.ultimatearmor.desc": "//TODO",
|
||||
"oritech.text.augment.ultimatearmor.desc.1": "//TODO",
|
||||
"oritech.text.augment.waterbreath": "//TODO",
|
||||
"oritech.text.augment.waterbreath.desc": "//TODO",
|
||||
"oritech.text.augment.waterbreath.desc.1": "//TODO",
|
||||
"oritech.text.augment.weaponreach": "//TODO",
|
||||
"oritech.text.augment.weaponreach.desc": "//TODO",
|
||||
"oritech.text.augment.weaponreach.desc.1": "//TODO",
|
||||
"oritech.text.augment_ingredient_tip": "//TODO",
|
||||
"oritech.text.augment_op.apply": "Применить",
|
||||
"oritech.text.augment_op.pending": "Изучение...",
|
||||
"oritech.text.augment_op.remove": "Удалить \\ Снять //TODO",
|
||||
"oritech.text.augment_op.research": "Изучить \\ Изучение //TODO",
|
||||
"oritech.text.augment_research_time": "//TODO",
|
||||
"oritech.text.augment_resource_cost": "//TODO",
|
||||
"oritech.text.augment_toggle": "//TODO",
|
||||
"oritech.text.energy_cost": "//TODO",
|
||||
"oritech.text.missing_requirements_title": "//TODO",
|
||||
"oritech.text.required_station": "//TODO",
|
||||
"rei.process.oritech:refinery": "Очистка",
|
||||
"tag.item.c.bananas": "Бананы",
|
||||
"tag.item.c.biodiesel": "Биодизель",
|
||||
"tag.item.c.clumps": "Глыбы",
|
||||
"tag.item.c.clumps.copper": "Медные глыбы",
|
||||
"tag.item.c.clumps.gold": "Золотые глыбы",
|
||||
"tag.item.c.clumps.iron": "Железные глыбы",
|
||||
"tag.item.c.clumps.nickel": "Никелевая пыль",
|
||||
"tag.item.c.clumps.platinum": "Платиновая пыль",
|
||||
"tag.item.c.dusts.plutonium": "Плутониевая пыль",
|
||||
"tag.item.c.dusts.uranium": "Урановая пыль",
|
||||
"tag.item.c.fuels.bio": "Био топливо",
|
||||
"tag.item.c.fuels.block.bio": "Блоки биотоплива",
|
||||
"tag.item.c.high_power_biodiesel": "Высокоэффективный биодизель",
|
||||
"tag.item.c.oil": "Нефть",
|
||||
"tag.item.c.ores.uranium": "Урановые руды",
|
||||
"tag.item.c.plastics": "Пластик",
|
||||
"tag.item.c.raw_materials.nickel": "Необработанный никель",
|
||||
"tag.item.c.raw_materials.platinum": "Необработанную платину",
|
||||
"tag.item.c.raw_materials.uranium": "Необработанный уран",
|
||||
"tag.item.c.steam": "Пар",
|
||||
"tag.item.c.tools.wrench": "Гаечные ключи",
|
||||
"tag.item.oritech.biofuel": "Биотопливо",
|
||||
"tag.item.oritech.biomatter": "Биоматерия",
|
||||
"tag.item.oritech.reactor_coolant_items": "Хладагенты",
|
||||
"tag.item.oritech.recyclable.biomass": "Перерабатывается в биомассу",
|
||||
"tag.item.oritech.recyclable.copper_dust": "Перерабатывается в медную пыль",
|
||||
"tag.item.oritech.recyclable.diamond": "Перерабатывается в алмаз",
|
||||
"tag.item.oritech.recyclable.gold_dust": "Перерабатывается в золотую пыль",
|
||||
"tag.item.oritech.recyclable.gravel": "Перерабатывается в гравий",
|
||||
"tag.item.oritech.recyclable.iron_dust": "Перерабатывается в железную пыль",
|
||||
"tag.item.oritech.recyclable.netherite_scrap": "Перерабатывается в незеритовый лом",
|
||||
"tag.item.oritech.recyclable.quartz_dust_2": "Перерабатывается в кварцевую пыль (2)",
|
||||
"tag.item.oritech.recyclable.quartz_dust_4": "Перерабатывается в кварцевую пыль (4)",
|
||||
"tag.item.oritech.recyclable.red_sand": "Перерабатывается в красный песок",
|
||||
"tag.item.oritech.recyclable.redstone_dust": "Перерабатывается в редстоуновую пыль",
|
||||
"tag.item.oritech.recyclable.sand": "Перерабатывается в песок",
|
||||
"tag.item.oritech.recyclable.small_copper_dust": "Перерабатывается в маленькую кучку медной пыли",
|
||||
"tag.item.oritech.recyclable.small_gold_dust": "Перерабатывается в маленькую кучку золотой пыли",
|
||||
"tag.item.oritech.recyclable.small_iron_dust": "Перерабатывается в маленькую кучку железной пыли",
|
||||
"tag.item.oritech.recyclable.string": "Перерабатывается в нить",
|
||||
"tag.item.oritech.turbofuel": "Турботопливо",
|
||||
"text.config.oritech-config.category.addonConfig": "Данные Модуля",
|
||||
"text.config.oritech-config.category.electricMace": "Электрическая булава",
|
||||
"text.config.oritech-config.category.portableLaserConfig": "Эндеритовый рельсотрон",
|
||||
"text.config.oritech-config.category.processingMachines.refineryData": "Настройки очистительного завода",
|
||||
"text.config.oritech-config.option.acceleratorMotorRFCapacity": "Емкость RF: Линейный двигатель ускорителя",
|
||||
"text.config.oritech-config.option.additiveAddons": "Тип множителя модулей",
|
||||
"text.config.oritech-config.option.additiveAddons.tooltip": "Позволяет выбрать тип множителя для модулей: сложение и перемножение.",
|
||||
"text.config.oritech-config.option.addonConfig.chamberAddonEfficiency": "//TODO",
|
||||
"text.config.oritech-config.option.addonConfig.efficiencyAddonEfficiency": "//TODO",
|
||||
"text.config.oritech-config.option.addonConfig.speedAddonEfficiency": "//TODO",
|
||||
"text.config.oritech-config.option.addonConfig.speedAddonSpeed": "//TODO",
|
||||
"text.config.oritech-config.option.addonConfig.ultimateAddonEfficiency": "//TODO",
|
||||
"text.config.oritech-config.option.addonConfig.ultimateAddonSpeed": "//TODO",
|
||||
"text.config.oritech-config.option.augmenterMaxEnergy": "//TODO",
|
||||
"text.config.oritech-config.option.boringNukes": "//TODO",
|
||||
"text.config.oritech-config.option.catalystHyperExpFactor": "//TODO",
|
||||
"text.config.oritech-config.option.catalystHyperExpFactor.tooltip": "//TODO",
|
||||
"text.config.oritech-config.option.chainsawTreeCutting": "//TODO",
|
||||
"text.config.oritech-config.option.electricMace.baseDamage": "//TODO",
|
||||
"text.config.oritech-config.option.electricMace.chargeSpeed": "//TODO",
|
||||
"text.config.oritech-config.option.electricMace.energyCapacity": "//TODO",
|
||||
"text.config.oritech-config.option.electricMace.energyUsage": "//TODO",
|
||||
"text.config.oritech-config.option.electricMace.lightningCostMultiplier": "//TODO",
|
||||
"text.config.oritech-config.option.enableHelpButton": "//TODO",
|
||||
"text.config.oritech-config.option.generateOresFabricOnly": "//TODO",
|
||||
"text.config.oritech-config.option.generateOresFabricOnly.tooltip": "//TODO",
|
||||
"text.config.oritech-config.option.generators.steamEngineData.rfToSteamRatio": "//TODO",
|
||||
"text.config.oritech-config.option.generators.steamEngineData.rfToSteamRatio.tooltip": "//TODO",
|
||||
"text.config.oritech-config.option.generators.steamEngineData.steamToRfRatio": "//TODO",
|
||||
"text.config.oritech-config.option.generators.steamEngineData.stopOnEnergyFull": "//TODO",
|
||||
"text.config.oritech-config.option.generators.steamEngineData.stopOnEnergyFull.tooltip": "//TODO",
|
||||
"text.config.oritech-config.option.generators.steamEngineData.stopOnWaterFull": "//TODO",
|
||||
"text.config.oritech-config.option.generators.steamEngineData.stopOnWaterFull.tooltip": "//TODO",
|
||||
"text.config.oritech-config.option.generators.steamId": "//TODO",
|
||||
"text.config.oritech-config.option.generators.steamId.tooltip": "//TODO",
|
||||
"text.config.oritech-config.option.layeredExtenders": "//TODO",
|
||||
"text.config.oritech-config.option.layeredExtenders.tooltip": "//TODO",
|
||||
"text.config.oritech-config.option.portableLaserConfig.blockBreakSpeed": "//TODO",
|
||||
"text.config.oritech-config.option.portableLaserConfig.damageBase": "//TODO",
|
||||
"text.config.oritech-config.option.portableLaserConfig.energyCapacity": "//TODO",
|
||||
"text.config.oritech-config.option.portableLaserConfig.energyPerBoom": "//TODO",
|
||||
"text.config.oritech-config.option.portableLaserConfig.energyPerTick": "//TODO",
|
||||
"text.config.oritech-config.option.portableLaserConfig.explosionStrength": "//TODO",
|
||||
"text.config.oritech-config.option.processingMachines.refineryData.energyCapacity": "//TODO",
|
||||
"text.config.oritech-config.option.processingMachines.refineryData.energyPerTick": "//TODO",
|
||||
"text.config.oritech-config.option.processingMachines.refineryData.maxEnergyExtraction": "//TODO",
|
||||
"text.config.oritech-config.option.processingMachines.refineryData.maxEnergyInsertion": "//TODO",
|
||||
"text.config.oritech-config.option.reactorMaxEnergyOutput": "//TODO",
|
||||
"text.config.oritech-config.option.reactorMaxEnergyStored": "//TODO",
|
||||
"text.config.oritech-config.option.showMachinePreview": "//TODO",
|
||||
"text.config.oritech-config.option.unstableContainerBaseCapacity": "//TODO",
|
||||
"text.config.oritech-config.section.augments": "//TODO",
|
||||
"text.oritech.augmenter_active": "Осталось: %s сек.",
|
||||
"text.oritech.augmenter_creative_tooltip": "В творческом режиме вы можете исследовать / применять улучшения без необходимых ресурсов.",
|
||||
"text.oritech.begin_research": "Начать изучение",
|
||||
"text.oritech.cancel": "Отмена",
|
||||
"text.oritech.install": "Установить",
|
||||
"text.oritech.load_augments.tooltip": "Загрузить информацию о киберимплантах игрока в механизм",
|
||||
"text.oritech.loaded_augments": "Загружено киберимплантов: %s",
|
||||
"text.oritech.noop": "",
|
||||
"text.oritech.open_inv.tooltip": "",
|
||||
"text.oritech.remove": "",
|
||||
"text.oritech.unstable_container_blocked": "",
|
||||
"title.oritech.energy.inAvgSecond": "",
|
||||
"title.oritech.energy.inAvgSecond.tooltip": "",
|
||||
"title.oritech.energy.inLastTick": "",
|
||||
"title.oritech.energy.inLastTick.tooltip": "",
|
||||
"title.oritech.energy.inPeak": "",
|
||||
"title.oritech.energy.inPeak.tooltip": "",
|
||||
"title.oritech.energy.inSources": "",
|
||||
"title.oritech.energy.inSources.tooltip": "",
|
||||
"title.oritech.energy.outAvgSecond": "",
|
||||
"title.oritech.energy.outAvgSecond.tooltip": "",
|
||||
"title.oritech.energy.outLastTick": "",
|
||||
"title.oritech.energy.outLastTick.tooltip": "",
|
||||
"title.oritech.energy.outPeak": "",
|
||||
"title.oritech.energy.outPeak.tooltip": "",
|
||||
"title.oritech.item_filter.component": "",
|
||||
"title.oritech.item_filter.toggle_energy_statistics": "",
|
||||
"tooltip.oritech.addon_silk_touch_desc": "",
|
||||
"tooltip.oritech.augment_research_station": "",
|
||||
"tooltip.oritech.augmenter.1": "",
|
||||
"tooltip.oritech.augmenter.2": "",
|
||||
"tooltip.oritech.electric_mace": "",
|
||||
"tooltip.oritech.electric_mace.1": "",
|
||||
"tooltip.oritech.fluid_content_tank_tooltip": "",
|
||||
"tooltip.oritech.item_filter.component": "",
|
||||
"tooltip.oritech.item_filter.no_component": "",
|
||||
"tooltip.oritech.item_pipe.1": "",
|
||||
"tooltip.oritech.item_pipe.2": "фыафыаафы",
|
||||
"tooltip.oritech.item_pipe.3": "",
|
||||
"tooltip.oritech.item_pipe.4": "",
|
||||
"tooltip.oritech.laser_arm_block.extra": "",
|
||||
"tooltip.oritech.machine.addon_silk_touch": "",
|
||||
"tooltip.oritech.machine.byproduct_bonus.tooltip": "",
|
||||
"tooltip.oritech.machine_core_block": "",
|
||||
"tooltip.oritech.machine_frame.1": "",
|
||||
"tooltip.oritech.motor": "",
|
||||
"tooltip.oritech.oracle_available": "",
|
||||
"tooltip.oritech.oracle_missing": "",
|
||||
"tooltip.oritech.portable_laser.1": "",
|
||||
"tooltip.oritech.portable_laser.2": "",
|
||||
"tooltip.oritech.portable_laser.3": "",
|
||||
"text.oritech.open_inv.tooltip": "Открыть центр кибернетических улучшений",
|
||||
"text.oritech.remove": "Убрать",
|
||||
"text.oritech.unstable_container_blocked": "Невозможно поставить, область заблокирована.",
|
||||
"title.oritech.energy.inAvgSecond": "∅ %s RF/t",
|
||||
"title.oritech.energy.inAvgSecond.tooltip": "Средний RF/t полученный за последнюю секунду.",
|
||||
"title.oritech.energy.inLastTick": "📈 %s RF/t",
|
||||
"title.oritech.energy.inLastTick.tooltip": "Всего RF полученных за последний тик.",
|
||||
"title.oritech.energy.inPeak": "📊 %s RF/t",
|
||||
"title.oritech.energy.inPeak.tooltip": "Пиковый RF/t полученный за последнюю секунду.",
|
||||
"title.oritech.energy.inSources": "%s Источник(ов)",
|
||||
"title.oritech.energy.inSources.tooltip": "Количество событий получения RF за последний тик\n(Например, количество механизмов/блоков которые отдали энергию).",
|
||||
"title.oritech.energy.outAvgSecond": "∅ %s RF/t",
|
||||
"title.oritech.energy.outAvgSecond.tooltip": "Средняя отдача RF/t за последнюю секунду.",
|
||||
"title.oritech.energy.outLastTick": "📈 %s RF/t",
|
||||
"title.oritech.energy.outLastTick.tooltip": "Количество RF, которое было отдано из этого блока за последний тик.",
|
||||
"title.oritech.energy.outPeak": "📊 %s RF/t",
|
||||
"title.oritech.energy.outPeak.tooltip": "Пиковая отдача RF/t за последнюю секунду.",
|
||||
"title.oritech.item_filter.component": "Компоненты",
|
||||
"title.oritech.item_filter.toggle_energy_statistics": "Показать выход",
|
||||
"tooltip.oritech.addon_silk_touch_desc": "Применяет эффект шёлкового касания к блокам, которые сломаны эндеритовым лазером и разрушителем блоков.",
|
||||
"tooltip.oritech.augment_research_station": "Строится на портах исследовательской станции, аналогично портам модулей.",
|
||||
"tooltip.oritech.augmenter.1": "Используется для изучения, снятия и установки киберимплантов.",
|
||||
"tooltip.oritech.augmenter.2": "Удерживайте [%s] чтобы настроить установленные киберимпланты.",
|
||||
"tooltip.oritech.electric_mace": "При атаке выпускает небольшую молнию. Работает аналогично обычной булаве.",
|
||||
"tooltip.oritech.electric_mace.1": "Булавы наносят повышенный урон при атаке в падении с большой высоты.",
|
||||
"tooltip.oritech.fluid_content_tank_tooltip": "%fB %s",
|
||||
"tooltip.oritech.item_filter.component": "Проверяет все указанные предметы на полное соответствие дата-компонентов",
|
||||
"tooltip.oritech.item_filter.no_component": "Игнорирует все дата-компоненты предмета, такие как зачарования, энергия и т.д.",
|
||||
"tooltip.oritech.item_pipe.1": "Нажмите ПКМ чтобы включить/выключить извлечение.",
|
||||
"tooltip.oritech.item_pipe.2": "Извлекает предметы только из первого не пустого слота.",
|
||||
"tooltip.oritech.item_pipe.3": [
|
||||
"Нажмите ПКМ с ",
|
||||
{
|
||||
"text": "мотором",
|
||||
"color": "#ff830e"
|
||||
},
|
||||
" в руке, чтобы улучшить трубу. Теперь она извлекает предметы из всех слотов сразу!"
|
||||
],
|
||||
"tooltip.oritech.item_pipe.4": "Складывает предметы в ближайший доступный инвентарь.",
|
||||
"tooltip.oritech.laser_arm_block.extra": "Также можно поставить на стены и потолки.",
|
||||
"tooltip.oritech.machine.addon_silk_touch": "Когда модуль шёлкового касания и модуль удачи устанавливаются одновременно, приоритет отдается модулю шёлкового касания.",
|
||||
"tooltip.oritech.machine.byproduct_bonus.tooltip": "Установлен модуль удачи. Побочные продукты удваиваются.",
|
||||
"tooltip.oritech.machine_core_block": "Улучшенные ядра позволяют подключать больше расширителей модулей а не самих модулей!",
|
||||
"tooltip.oritech.machine_frame.1": "Максимальная длина: %sx%s блоков.",
|
||||
"tooltip.oritech.motor": "Нажмите ПКМ по трубе чтобы улучшить её. Теперь она будет извлекать предметы из всех слотов сразу!",
|
||||
"tooltip.oritech.oracle_available": "Открыть соответствующую страницу справки в Oracle Index.",
|
||||
"tooltip.oritech.oracle_missing": "Вики-мод Oracle Index не установлен. Справка в игре недоступна.",
|
||||
"tooltip.oritech.portable_laser.1": "Нажатие ЛКМ выпускает непрерывный луч, который может передавать энергию, ломать блоки, наносить урон",
|
||||
"tooltip.oritech.portable_laser.2": "и преобразовывать разрушенные предметы как эндеритовый лазер.",
|
||||
"tooltip.oritech.portable_laser.3": "Нажатие ПКМ создает высокоэнергетический взрыв.",
|
||||
"tooltip.oritech.portable_laser.4": "",
|
||||
"tooltip.oritech.portable_laser.5": "",
|
||||
"tooltip.oritech.portable_laser.status.begin": "",
|
||||
"tooltip.oritech.portable_laser.status.hint": "",
|
||||
"tooltip.oritech.portable_laser.status.shot_mining_error": "",
|
||||
"tooltip.oritech.pump_redstone": "",
|
||||
"tooltip.oritech.reactor_energy_port.rate": "",
|
||||
"tooltip.oritech.refinery_block": "",
|
||||
"tooltip.oritech.refinery_module": "",
|
||||
"tooltip.oritech.refinery_module_count": "",
|
||||
"tooltip.oritech.steam_engine.1": "",
|
||||
"tooltip.oritech.steam_engine.2": "",
|
||||
"tooltip.oritech.steam_workers": "",
|
||||
"tooltip.oritech.trillion_abbrev": "",
|
||||
"tooltip.oritech.unstable_contained_tooltip": "",
|
||||
"tooltip.oritech.unstable_container.1": "",
|
||||
"tooltip.oritech.unstable_container.2": "",
|
||||
"tooltip.oritech.unstable_container.3": "",
|
||||
"tooltip.oritech.portable_laser.5": "Работает с большинством зачарований для кирки, прочностью и остротой.",
|
||||
"tooltip.oritech.portable_laser.status.begin": "Режим копания:",
|
||||
"tooltip.oritech.portable_laser.status.hint": "(Shift + ПКМ для переключения)",
|
||||
"tooltip.oritech.portable_laser.status.shot_mining_error": "Высокоэнергетический взрыв не был произведён, так как включён режим копания.",
|
||||
"tooltip.oritech.pump_redstone": "Может быть отключен с помощью редстоун сигнала.",
|
||||
"tooltip.oritech.reactor_energy_port.rate": "Макс. передача: %s RF/t.",
|
||||
"tooltip.oritech.refinery_block": "Можно подключить до 2 перегонных кубов на верх очистительного завода.",
|
||||
"tooltip.oritech.refinery_module": "Можно подключить до 2 перегонных кубов на верх очистительного завода.",
|
||||
"tooltip.oritech.refinery_module_count": "Два дополнительных модуля перегонных кубов могут быть установлены сверху, чтобы разблокировать оставшиеся резервуары.\nОтсутствие модулей удваивает производство жидкости в первом резервуаре.\nОдин модуль удваивает только производство жидкости во втором резервуаре.\nНаличие двух модулей разблокирует все резервуары и не даёт бонусов к производимым жидкостям.",
|
||||
"tooltip.oritech.steam_engine.1": "путём установки двигателей в одну линию. Можно взаимодействовать только",
|
||||
"tooltip.oritech.steam_engine.2": "с первым двигателем. (Например, подавайте пар только в первый двигатель).",
|
||||
"tooltip.oritech.steam_workers": "Объединенные в цепочку двигатели будут совместно использовать резервуар для пара и воды этого блока.",
|
||||
"tooltip.oritech.trillion_abbrev": "T",
|
||||
"tooltip.oritech.unstable_contained_tooltip": "Множитель возможностей сейфа. Чем больше опасных блоков, тем лучше.",
|
||||
"tooltip.oritech.unstable_container.1": "Используется для хранения и преобразования опасных блоков. Нажмите ПКМ по блоку с этим предметом в руке и",
|
||||
"tooltip.oritech.unstable_container.2": "он захватит блок как ядро огромного мультиблочного хранилища энергии.",
|
||||
"tooltip.oritech.unstable_container.3": "Стабилизация сейфа с помощью эндеритового лазера даст экспоненциальное увеличение количества энергии которую он может хранить.",
|
||||
"tooltip.oritech.unstable_container.4": "",
|
||||
"tooltip.oritech.unstable_container.5": "",
|
||||
"tooltip.oritech.unstable_container.high": "",
|
||||
"tooltip.oritech.unstable_container.low": "",
|
||||
"tooltip.oritech.unstable_container.medium": "",
|
||||
"tooltip.oritech.unstable_container_extra_info": "фыфф",
|
||||
"tooltip.oritech.unstable_laser_tooltip": "",
|
||||
"tooltip.oritech.unstable_laser_tooltip.2": ""
|
||||
"tooltip.oritech.unstable_container.5": "Выходы RF расположены сверху и снизу, а входы с остальных сторон.",
|
||||
"tooltip.oritech.unstable_container.high": "Высокоэнергетические блоки:",
|
||||
"tooltip.oritech.unstable_container.low": "Низкоэнергетические блоки:",
|
||||
"tooltip.oritech.unstable_container.medium": "Среднеэнергетические блоки:",
|
||||
"tooltip.oritech.unstable_container_extra_info": "Зажмите shift для просмотра подходящих блоков.",
|
||||
"tooltip.oritech.unstable_laser_tooltip": "Лазеры не будут добавлять ёмкость этому механизму. Вместо этого они увеличат",
|
||||
"tooltip.oritech.unstable_laser_tooltip.2": "количество блоков которые он может хранить. Это число увеличивается экспоненциально (максимум х5000)."
|
||||
}
|
||||
@@ -5,3 +5,6 @@ numpy==1.23.5
|
||||
PySocks==1.7.1
|
||||
setuptools==72.1.0
|
||||
wasmtime==35.0.0
|
||||
flask==3.0.3
|
||||
deepdiff==8.5.0
|
||||
python-dotenv==1.0.0
|
||||
+19
-19
@@ -84,12 +84,12 @@
|
||||
"tooltip.oritech.item_extra_info": "Зажмите Ctrl для дополнительной информации",
|
||||
"tooltip.oritech.addon_desc": "Слоты модулей: ",
|
||||
"tooltip.oritech.core_desc": "Мультиблок. Требуется ядер механизма: ",
|
||||
"tooltip.oritech.generator_rate_desc": "Выработка:",
|
||||
"tooltip.oritech.generator_rate_desc": "Генерация:",
|
||||
"tooltip.oritech.machine_rate_desc": "Потребление энергии: ",
|
||||
"tooltip.oritech.machine_capacity_desc": "Ёмкость энергии: ",
|
||||
"tooltip.oritech.solar_generation": "Скорость генерации зависит от качества ядра.",
|
||||
"tooltip.oritech.needs_laser_power": "Требуется питание от эндеритового лазера.",
|
||||
"tooltip.oritech.steam_engine": "Преобразует пар в RF и воду. Можно объединять в цепочки.",
|
||||
"tooltip.oritech.steam_engine": "Преобразует пар в RF и воду. Можно объединять в цепочки, ",
|
||||
"tooltip.oritech.item_filter": "Используется для фильтрации предметов которые поступают в инвентарь.",
|
||||
"tooltip.oritech.machine_frame": "Да, в конфигах можно изменить её хитбокс.",
|
||||
"tooltip.oritech.particle_collector": "Собирает энергию тахионов из столкновений частиц.",
|
||||
@@ -123,14 +123,14 @@
|
||||
"tooltip.oritech.charger": "Заряжает и заправляет оборудование.",
|
||||
"tooltip.oritech.addon_speed_desc": "Скорость работы ",
|
||||
"tooltip.oritech.addon_efficiency_desc": "Энергоэффективность ",
|
||||
"tooltip.oritech.addon_yield_desc": "Удваивает побочные продукты в комплексе переработки. Увеличивает добычу в разрушителе блоков и эндеритовом лазере",
|
||||
"tooltip.oritech.addon_yield_desc": "Удваивает побочные продукты в комплексе переработки. Увеличивает добычу в разрушителе блоков и эндеритовом лазере.",
|
||||
"tooltip.oritech.processing_addon_desc": "Позволяет обрабатывать +1 рецепт за цикл.",
|
||||
"tooltip.oritech.addon_fluid_desc": "Добавляет обработку с жидкостями (центрифуга, док-станция дронов).",
|
||||
"tooltip.oritech.addon_acceptor_desc": "Позволяет вводить энергию напрямую в модуль, вместо механизма.",
|
||||
"tooltip.oritech.addon_crop_desc": "Применяется к разрушителю блоков и эндеритовому лазеру. Игнорирует незрелые растения и животных",
|
||||
"tooltip.oritech.addon_crop_desc": "Применяется к разрушителю блоков и эндеритовому лазеру. Игнорирует незрелые растения и животных.",
|
||||
"tooltip.oritech.addon_proxy_desc": "Даёт доступ к определённым слотам инвентаря.",
|
||||
"tooltip.oritech.addon_proxy_select": "Выберите целевой слот",
|
||||
"tooltip.oritech.addon_quarry_desc": "Применяется к разрушителю блоков и эндеритовому лазеру. Увеличивает область работы",
|
||||
"tooltip.oritech.addon_quarry_desc": "Применяется к разрушителю блоков и эндеритовому лазеру. Увеличивает область работы.",
|
||||
"tooltip.oritech.addon_hunter_desc": "Применяется к эндеритовому лазеру. Нацеливается на живых существ.. Турель?",
|
||||
"tooltip.oritech.addon_redstone_desc": "Расширенные настройки для редстоуна и компаратора.",
|
||||
"tooltip.oritech.addon_capacity_desc": "Ёмкость энергии: ",
|
||||
@@ -259,7 +259,7 @@
|
||||
"tooltip.oritech.block_destroyer.addon_range": "Макс. глубина добычи",
|
||||
"tooltip.oritech.laser_arm.addon_range": "Эффективный радиус луча",
|
||||
"title.oritech.machine.addon_fortune": "Удача: %d",
|
||||
"tooltip.oritech.machine.addon_fortune": "Количество модулей продуктивности.\nЭффективный максимум — 3 штуки.",
|
||||
"tooltip.oritech.machine.addon_fortune": "Количество модулей удачи.\nЭффективный максимум — 3 штуки.",
|
||||
"tooltip.oritech.machine.quality": "Качество механизма: %d\n\nОпределяет сколько модулей можно установить.\nИспользуйте улучшенные ядра механизма для повышения качества.\nТекущий прогресс качества: %s",
|
||||
"tooltip.oritech.thousand_abbrev": "Тыс.",
|
||||
"tooltip.oritech.million_abbrev": "Млн.",
|
||||
@@ -315,14 +315,14 @@
|
||||
"title.oritech.laser_arm.addon_hunter_damage": "%d Damage",
|
||||
"tooltip.oritech.laser_arm.addon_hunter_damage": "Эффективный урон луча",
|
||||
"title.oritech.machine.addon_looting": "Добыча: %d",
|
||||
"tooltip.oritech.machine.addon_looting": "Количество модулей продуктивности.\nЭффективный максимум — 3 штуки.",
|
||||
"tooltip.oritech.machine.addon_looting": "Количество модулей удачи.\nЭффективный максимум — 3 штуки.",
|
||||
"rei.process.oritech:pulverizer": "Измельчение",
|
||||
"rei.process.oritech:grinder": "Переработка",
|
||||
"rei.process.oritech:assembler": "Сборка",
|
||||
"rei.process.oritech:foundry": "Сплавление",
|
||||
"rei.process.oritech:cooler": "Охлаждение",
|
||||
"rei.process.oritech:centrifuge": "Центрифугирование",
|
||||
"rei.process.oritech:centrifuge_fluid": "Разделение жидкостей",
|
||||
"rei.process.oritech:centrifuge_fluid": "Жидкостное центрифугирование",
|
||||
"rei.process.oritech:atomic_forge": "Атомная реконструкция",
|
||||
"rei.process.oritech:lava_generator": "Сжигание лавы",
|
||||
"rei.process.oritech:steam_engine": "Использование пара",
|
||||
@@ -331,14 +331,14 @@
|
||||
"rei.process.oritech:particle_collision": "Столкновение частиц",
|
||||
"rei.process.oritech:reactor": "Заправка реактора",
|
||||
"rei.process.oritech:laser": "Разрушение блоков лазером",
|
||||
"rei.title.oritech.cookingtime": "%ds (%d тика(ов))",
|
||||
"rei.title.oritech.cookingtime": "%dсек. (%d тиков)",
|
||||
"emi.category.oritech.pulverizer": "Измельчение",
|
||||
"emi.category.oritech.grinder": "Переработка",
|
||||
"emi.category.oritech.assembler": "Сборка",
|
||||
"emi.category.oritech.foundry": "Сплавление",
|
||||
"emi.category.oritech.cooler": "Охлаждение",
|
||||
"emi.category.oritech.centrifuge": "Центрифугирование",
|
||||
"emi.category.oritech.centrifuge_fluid": "Разделение жидкостей",
|
||||
"emi.category.oritech.centrifuge_fluid": "Жидкостное центрифугирование",
|
||||
"emi.category.oritech.atomic_forge": "Атомная реконструкция",
|
||||
"emi.category.oritech.lava_generator": "Сжигание лавы",
|
||||
"emi.category.oritech.steam_engine": "Использование пара",
|
||||
@@ -347,7 +347,7 @@
|
||||
"emi.category.oritech.particle_collision": "Столкновение частиц",
|
||||
"emi.category.oritech.reactor": "Заправка реактора",
|
||||
"emi.category.oritech.laser": "Разрушение блоков лазером",
|
||||
"emi.title.oritech.cookingtime": "%ds (%d тика(ов))",
|
||||
"emi.title.oritech.cookingtime": "%dсек. (%d тиков)",
|
||||
"emi.title.oritech.collisionspeed": "Требуемая энергия столкновения: %sJ",
|
||||
"emi.title.oritech.laser_interaction": "Разрушение блоков лазером",
|
||||
"itemgroup.oritech.machines": "Механизмы Oritech",
|
||||
@@ -450,18 +450,18 @@
|
||||
"block.oritech.machine_core_5": "Элитное ядро механизма",
|
||||
"block.oritech.machine_core_6": "Ультимативное ядро механизма",
|
||||
"block.oritech.machine_core_7": "Совершенное ядро механизма",
|
||||
"block.oritech.machine_speed_addon": "Модуль: Ускорение",
|
||||
"block.oritech.machine_speed_addon": "Модуль: Разгон",
|
||||
"block.oritech.machine_processing_addon": "Модуль: Многопоточность",
|
||||
"block.oritech.machine_ultimate_addon": "Модуль: Матрица синергии",
|
||||
"block.oritech.machine_fluid_addon": "Модуль: Резервуар",
|
||||
"block.oritech.machine_yield_addon": "Модуль: Продуктивность",
|
||||
"block.oritech.machine_yield_addon": "Модуль: Удача",
|
||||
"block.oritech.steam_boiler_addon": "Модуль: Паровой котёл",
|
||||
"block.oritech.crop_filter_addon": "Модуль: Фильтр культур",
|
||||
"block.oritech.quarry_addon": "Модуль: Карьер",
|
||||
"block.oritech.machine_hunter_addon": "Модуль: Охотник",
|
||||
"block.oritech.machine_efficiency_addon": "Модуль: Эффективность",
|
||||
"block.oritech.machine_capacitor_addon": "Модуль: Конденсатор",
|
||||
"block.oritech.machine_acceptor_addon": "Модуль: Интерфейс энергии",
|
||||
"block.oritech.machine_efficiency_addon": "Модуль: Энергоэффективность",
|
||||
"block.oritech.machine_capacitor_addon": "Модуль: Второй конденсатор",
|
||||
"block.oritech.machine_acceptor_addon": "Модуль: Повышающий трансформатор",
|
||||
"block.oritech.machine_inventory_proxy_addon": "Модуль: Интерфейс инвентаря",
|
||||
"block.oritech.machine_redstone_addon": "Модуль: Контроль редстоуном",
|
||||
"block.oritech.capacitor_addon_extender": "Модуль: Продвинутый конденсатор",
|
||||
@@ -551,7 +551,7 @@
|
||||
"block.oritech.accelerator_ring": "Направляющее кольцо ускорителя",
|
||||
"block.oritech.accelerator_motor": "Линейный двигатель ускорителя",
|
||||
"block.oritech.accelerator_controller": "Ускоритель частиц",
|
||||
"block.oritech.accelerator_sensor": "Датчик скорости частиц",
|
||||
"block.oritech.accelerator_sensor": "Измеритель скорости частиц",
|
||||
"block.oritech.reactor_controller": [
|
||||
{
|
||||
"text": "Контроллер ядерного реактора",
|
||||
@@ -705,7 +705,7 @@
|
||||
],
|
||||
"message.oritech.catalyst.cost": "Стоимость: %d",
|
||||
"message.oritech.deep_drill.ore_placement": "Механизм должен стоять на месторождениях руды.",
|
||||
"message.oritech.generator.production_rate": "Выработка: %d (Множитель ядра: %d)",
|
||||
"message.oritech.generator.production_rate": "Генерация: %d (Множитель ядра: %d)",
|
||||
"message.oritech.machine.missing_core": "Машина не собрана. Установите недостающие ядра механизма.",
|
||||
"message.oritech.machine_frame.missing_frame": "Отсутствует рама. Постройте прямоугольную раму из блоков рамки механизма",
|
||||
"message.oritech.enchanter.insert_item": "Положите предмет",
|
||||
@@ -733,7 +733,7 @@
|
||||
"tooltip.oritech.target_designator.no_target": "Цель не задана",
|
||||
"tooltip.oritech.pipe_duct_warning": "Соединяется только с трубами. НЕ С МЕХАНИЗМАМИ!",
|
||||
"message.oritech.tool_mode.area_effect": "Копает 3х1",
|
||||
"message.oritech.tool_mode.silk_touch": "Шёлковое касание",
|
||||
"message.oritech.tool_mode.silk_touch": "Шёлковое касание (При зажатом Shift)",
|
||||
"tooltip.oritech.tool_mode.area_range.area": "Режим: область",
|
||||
"tooltip.oritech.tool_mode.area_range.single": "Режим: одиночный",
|
||||
"message.oritech.reactor_edge_invalid": "Ошибка: края реактора должны быть прямоугольными",
|
||||
|
||||
+104
-3
@@ -9,6 +9,7 @@
|
||||
--medium-gray: #ddd;
|
||||
--dark-gray: #666;
|
||||
--purple: #673ab7;
|
||||
--pastel-pinpurle: #b73ab7;
|
||||
--deep-purple: #5c6bc0;
|
||||
--brown: #795548;
|
||||
}
|
||||
@@ -189,7 +190,7 @@ h1 {
|
||||
box-shadow: 0 0 0 2px rgba(74, 144, 226, 0.2);
|
||||
}
|
||||
|
||||
.copy-btn, .suggest-btn, .copy-clipboard-btn, .undo-btn, .redo-btn {
|
||||
.copy-btn, .suggest-btn, .copy-clipboard-btn, .undo-btn, .redo-btn, .mark-todo-btn, .resolve-todo-btn{
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
padding: 6px 12px;
|
||||
@@ -202,6 +203,86 @@ h1 {
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.mark-todo-btn {
|
||||
background-color: var(--warning-color);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.mark-todo-btn:hover {
|
||||
background-color: #e68a00;
|
||||
}
|
||||
|
||||
.resolve-todo-btn {
|
||||
background-color: var(--success-color);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.resolve-todo-btn:hover {
|
||||
background-color: #3d8b40;
|
||||
}
|
||||
|
||||
/* Highlight TODO items in translation tab */
|
||||
.textarea-with-todo {
|
||||
border-left: 3px solid var(--warning-color);
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.translation-input, .new-value, .old-value {
|
||||
white-space: pre-wrap; /* Preserve both spaces and line breaks */
|
||||
word-break: break-word; /* Break long words if needed */
|
||||
}
|
||||
|
||||
.show-control-chars::before {
|
||||
content: "\\A";
|
||||
white-space: pre;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.translation-input {
|
||||
font-family: Consolas, monospace; /* Use monospace font to better see whitespace */
|
||||
}
|
||||
|
||||
/* For displaying values in diffs */
|
||||
.new-value, .old-value {
|
||||
font-family: Consolas, monospace;
|
||||
display: inline-block;
|
||||
max-width: 100%;
|
||||
overflow-x: auto;
|
||||
background-color: rgba(0,0,0,0.05);
|
||||
padding: 2px 6px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
/* CAN LEAD TO ERROR */
|
||||
textarea {
|
||||
white-space: pre;
|
||||
overflow-wrap: normal;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
/* Стили для визуализации пробелов и переносов */
|
||||
.whitespace {
|
||||
position: relative;
|
||||
}
|
||||
.whitespace-space::before {
|
||||
content: "·";
|
||||
color: #aaa;
|
||||
position: absolute;
|
||||
}
|
||||
.whitespace-tab::before {
|
||||
content: "→";
|
||||
color: #99f;
|
||||
position: absolute;
|
||||
}
|
||||
.whitespace-newline {
|
||||
/* display: inline-block; */
|
||||
width: 100%;
|
||||
}
|
||||
.whitespace-newline::after {
|
||||
content: "↵";
|
||||
color: #f99;
|
||||
margin-left: 2px;
|
||||
}
|
||||
|
||||
.copy-btn {
|
||||
background-color: #7fb3d5;
|
||||
color: white;
|
||||
@@ -248,6 +329,14 @@ h1 {
|
||||
background-color: #5e35b1;
|
||||
}
|
||||
|
||||
.learning-ai {
|
||||
background-color: var(--pastel-pinpurle) !important;
|
||||
}
|
||||
|
||||
.learning-ai:hover {
|
||||
background-color: #b1358c !important;
|
||||
}
|
||||
|
||||
.suggestion-btn-row {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
@@ -482,7 +571,7 @@ h1 {
|
||||
|
||||
.setting-input, .setting-textarea, .setting-select {
|
||||
width: 100%; /* Will take full width of parent .setting-control */
|
||||
max-width: 300px; /* Maximum width to prevent over-expansion */
|
||||
/* max-width: 300px; */
|
||||
padding: 8px 12px;
|
||||
border: 1px solid var(--medium-gray);
|
||||
border-radius: 4px;
|
||||
@@ -693,4 +782,16 @@ input:checked + .slider:before {
|
||||
|
||||
.toast-notification.warning {
|
||||
background-color: var(--warning-color);
|
||||
}
|
||||
}
|
||||
|
||||
/* Add this to your CSS */
|
||||
#markedTodo .key-item {
|
||||
border-left: 3px solid var(--warning-color);
|
||||
padding-left: 12px;
|
||||
}
|
||||
|
||||
#markedTodo .new-value {
|
||||
color: var(--warning-color);
|
||||
background-color: rgba(255, 152, 0, 0.1);
|
||||
}
|
||||
|
||||
|
||||
+297
-10
@@ -41,12 +41,47 @@ function copyToTranslation(key, value, inputId) {
|
||||
setTimeout(() => btn.textContent = originalText, 2000);
|
||||
}
|
||||
|
||||
function visualizeWhitespace(element) {
|
||||
const text = element.textContent || element.value;
|
||||
let html = '';
|
||||
|
||||
// console.log("Visualating whitespace for: " + text)
|
||||
if (text === undefined){
|
||||
return ' '
|
||||
}
|
||||
for (let i = 0; i < text.length; i++) {
|
||||
const char = text[i];
|
||||
if (char === ' ') {
|
||||
html += '<span class="whitespace whitespace-space"> </span>';
|
||||
} else if (char === '\t') {
|
||||
html += '<span class="whitespace whitespace-tab">\t</span>';
|
||||
} else if (char === '\n') {
|
||||
html += '<span class="whitespace-newline">\n</span>';
|
||||
} else {
|
||||
html += char;
|
||||
}
|
||||
}
|
||||
|
||||
return html;
|
||||
}
|
||||
|
||||
function applyWhitespaceVisualization() {
|
||||
// Для значений в DeepDiff
|
||||
document.querySelectorAll('.old-value, .new-value').forEach(el => {
|
||||
el.innerHTML = visualizeWhitespace(el);
|
||||
});
|
||||
}
|
||||
|
||||
// Modify the copyToClipboard function to preserve newlines
|
||||
function copyToClipboard(event, text) {
|
||||
event.preventDefault();
|
||||
const btn = event.currentTarget;
|
||||
const originalText = btn.textContent;
|
||||
|
||||
navigator.clipboard.writeText(text).then(() => {
|
||||
// Preserve the exact text including newlines and spaces
|
||||
const textToCopy = text.replace(/\\n/g, '\n'); // Convert \n to actual newlines
|
||||
|
||||
navigator.clipboard.writeText(textToCopy).then(() => {
|
||||
btn.textContent = 'Copied!';
|
||||
btn.classList.add('copied');
|
||||
setTimeout(() => {
|
||||
@@ -57,7 +92,7 @@ function copyToClipboard(event, text) {
|
||||
// Fallback for older browsers
|
||||
try {
|
||||
const textarea = document.createElement('textarea');
|
||||
textarea.value = text;
|
||||
textarea.value = textToCopy;
|
||||
document.body.appendChild(textarea);
|
||||
textarea.select();
|
||||
document.execCommand('copy');
|
||||
@@ -166,7 +201,7 @@ async function getAISuggestions(text, inputId, containerId) {
|
||||
const response = await fetch('/get_ai_suggestions', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({text: text})
|
||||
body: JSON.stringify({text: text.replace("\n", "\\n")})
|
||||
});
|
||||
const data = await response.json();
|
||||
|
||||
@@ -214,6 +249,69 @@ async function getAISuggestions(text, inputId, containerId) {
|
||||
}
|
||||
}
|
||||
|
||||
async function getLearningAISuggestions(text, inputId, containerId) {
|
||||
const container = document.getElementById(containerId);
|
||||
container.style.display = 'block';
|
||||
container.innerHTML = `
|
||||
<div class="suggestions-header">
|
||||
<span>Learning AI Translation Suggestions</span>
|
||||
<span class="close-suggestions" onclick="closeSuggestions('${containerId}', true)">×</span>
|
||||
</div>
|
||||
<div class="loading">Loading Learning AI suggestions...</div>
|
||||
`;
|
||||
|
||||
try {
|
||||
const response = await fetch('/get_learning_ai_suggestions', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({text: text.replace("\n", "\\n")})
|
||||
});
|
||||
const data = await response.json();
|
||||
|
||||
if (data.error) {
|
||||
container.innerHTML = `
|
||||
<div class="suggestions-header">
|
||||
<span>Error getting Learning AI suggestions</span>
|
||||
<span class="close-suggestions" onclick="closeSuggestions('${containerId}', true)">×</span>
|
||||
</div>
|
||||
<div class="error-message">${data.error}</div>
|
||||
`;
|
||||
return;
|
||||
}
|
||||
|
||||
let html = `
|
||||
<div class="suggestions-header">
|
||||
<span>Learning AI Translation Suggestions</span>
|
||||
<span class="close-suggestions" onclick="closeSuggestions('${containerId}', true)">×</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
if (data.suggestions?.length > 0) {
|
||||
data.suggestions.forEach((suggestion, index) => {
|
||||
html += `
|
||||
<div class="ai-suggestion" onclick="useSuggestion('${inputId}', '${escapeHtml(suggestion)}')">
|
||||
<span class="suggestion-number">${index + 1}.</span>
|
||||
${suggestion}
|
||||
</div>
|
||||
`;
|
||||
|
||||
});
|
||||
} else {
|
||||
html += `<div class="error-message">No Learning AI suggestions available</div>`;
|
||||
}
|
||||
|
||||
container.innerHTML = html;
|
||||
} catch (error) {
|
||||
container.innerHTML = `
|
||||
<div class="suggestions-header">
|
||||
<span>Error getting Learning AI suggestions</span>
|
||||
<span class="close-suggestions" onclick="closeSuggestions('${containerId}', true)">×</span>
|
||||
</div>
|
||||
<div class="error-message">Error loading Learning AI suggestions: ${error.message}</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
function closeSuggestions(containerId, clearContent = false) {
|
||||
const container = document.getElementById(containerId);
|
||||
container.style.display = 'none';
|
||||
@@ -252,9 +350,14 @@ function openTab(evt, tabName) {
|
||||
tablinks[i].classList.remove("active");
|
||||
}
|
||||
|
||||
if (tabName === 'markedTodo') {
|
||||
updateTodoTab();
|
||||
}
|
||||
|
||||
document.getElementById(tabName).classList.add("active");
|
||||
evt.currentTarget.classList.add("active");
|
||||
|
||||
applyWhitespaceVisualization();
|
||||
initAutoResizeTextareas();
|
||||
}
|
||||
|
||||
@@ -282,11 +385,13 @@ function collectTranslations() {
|
||||
|
||||
textareas.forEach(textarea => {
|
||||
const key = textarea.id.replace('input-', '');
|
||||
console.log(key)
|
||||
const originalKey = document.querySelector(`#translation-${key} .key`).textContent;
|
||||
let value = textarea.value.trim();
|
||||
if (value.startsWith("[{")) {
|
||||
let value = textarea.value;
|
||||
if (value.startsWith("[") && value.endsWith("]")) {
|
||||
translations[originalKey] = eval(value);
|
||||
console.warn("EVALED")
|
||||
console.warn("EVALED: " + value)
|
||||
console.warn("EVALED: " + eval(value))
|
||||
} else {
|
||||
translations[originalKey] = value;
|
||||
}
|
||||
@@ -295,15 +400,177 @@ function collectTranslations() {
|
||||
return translations;
|
||||
}
|
||||
|
||||
function markAsTodo(inputId) {
|
||||
const textarea = document.getElementById(inputId);
|
||||
if (!textarea.value.includes('//TODO')) {
|
||||
textarea.value = textarea.value + ' //TODO';
|
||||
autoResizeTextarea(textarea);
|
||||
addToHistory(textarea);
|
||||
showToast('Marked as TODO', 'success');
|
||||
} else {
|
||||
showToast('Already marked as TODO', 'info');
|
||||
}
|
||||
}
|
||||
|
||||
function collectTodoItems() {
|
||||
const todoItems = [];
|
||||
const textareas = document.querySelectorAll('#translation .translation-input');
|
||||
|
||||
textareas.forEach(textarea => {
|
||||
if (textarea.value.includes('//TODO') || textarea.value.includes('//REDO')) {
|
||||
const key = textarea.id.replace('input-', '');
|
||||
const keyElement = document.querySelector(`#translation-${key} .key`);
|
||||
const valueElement = document.querySelector(`#translation-${key} .new-value`);
|
||||
|
||||
if (keyElement && valueElement) {
|
||||
todoItems.push({
|
||||
key: keyElement.textContent,
|
||||
value: valueElement.textContent,
|
||||
translation: textarea.value
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return todoItems;
|
||||
}
|
||||
|
||||
function updateTodoTab() {
|
||||
const todoTab = document.getElementById('markedTodo');
|
||||
if (!todoTab) return;
|
||||
|
||||
const todoItems = collectTodoItems();
|
||||
const todoList = todoTab.querySelector('.key-list');
|
||||
|
||||
if (todoItems.length === 0) {
|
||||
todoList.innerHTML = '<p>No TODO/REDO items found. Mark items in the Translation tab by adding //TODO.</p>';
|
||||
return;
|
||||
}
|
||||
|
||||
let html = '<h3>TODO/REDO Items (' + todoItems.length + ')</h3>';
|
||||
|
||||
todoItems.forEach((item, index) => {
|
||||
html += `
|
||||
<div class="key-item" id="todo-translation-${index}">
|
||||
<div class="key-value-row">
|
||||
<span class="key">${item.key}</span>:
|
||||
<span class="new-value">${item.value}</span>
|
||||
</div>
|
||||
<div class="translation-row">
|
||||
<textarea class="translation-input"
|
||||
id="todo-input-${index}"
|
||||
placeholder="Enter translation...">${item.translation}</textarea>
|
||||
</div>
|
||||
<div class="suggestion-btn-row">
|
||||
<button class="copy-btn" onclick="copyToTranslation('${item.key}', '${escapeHtml(item.value)}', 'todo-input-${index}')">
|
||||
Copy to Translation
|
||||
</button>
|
||||
<button class="copy-clipboard-btn" onclick="copyToClipboard(event, '${escapeHtml(item.value)}')">
|
||||
Copy to Clipboard
|
||||
</button>
|
||||
<button class="suggest-btn" onclick="getTranslationSuggestions('${escapeHtml(item.value)}', 'todo-input-${index}', 'todo_suggestions-${index}')">
|
||||
Get Translations
|
||||
</button>
|
||||
<button class="suggest-btn ai-suggest-btn" onclick="getAISuggestions('${escapeHtml(item.value)}', 'todo-input-${index}', 'todo_ai-suggestions-${index}')">
|
||||
Get AI Suggestions
|
||||
</button>
|
||||
<button class="suggest-btn ai-suggest-btn learning-ai" onclick="getLearningAISuggestions('${escapeHtml(item.value)}', 'todo-input-${index}', 'todo_ai-suggestions-${index}')">
|
||||
Get Learning AI Suggestions
|
||||
</button>
|
||||
|
||||
<button class="copy-btn" onclick="copyToTranslation('${item.key}', '${escapeHtml(item.value)}', 'todo-input-${index}')">
|
||||
Copy Original
|
||||
</button>
|
||||
<button class="mark-todo-btn" onclick="markAsTodo('input-{{ loop.index }}')">
|
||||
Mark as TODO
|
||||
</button>
|
||||
<button class="resolve-todo-btn" onclick="resolveTodo('todo-input-${index}')">
|
||||
Resolve TODO
|
||||
</button>
|
||||
</div>
|
||||
<div class="undo-redo-buttons">
|
||||
<button class="undo-btn" onclick="undoChange('todo-input-${index}')">↩ Undo</button>
|
||||
<button class="redo-btn" onclick="redoChange('todo-input-${index}')">↪ Redo</button>
|
||||
</div>
|
||||
|
||||
<div class="suggestions-container" id="todo_suggestions-${index}"></div>
|
||||
<div class="ai-suggestions-container" id="todo_ai-suggestions-${index}"></div>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
todoList.innerHTML = html;
|
||||
initAutoResizeTextareas();
|
||||
}
|
||||
|
||||
function collectTodoTranslations() {
|
||||
const translations = {};
|
||||
const textareas = document.querySelectorAll('#markedTodo .translation-input');
|
||||
|
||||
textareas.forEach(textarea => {
|
||||
const key = textarea.id.replace('todo-input-', '');
|
||||
const originalKey = document.querySelector(`#todo-translation-${key} .key`).textContent;
|
||||
translations[originalKey] = textarea.value.trim();
|
||||
});
|
||||
|
||||
return translations;
|
||||
}
|
||||
|
||||
function resolveTodo(inputId) {
|
||||
const textarea = document.getElementById(inputId);
|
||||
textarea.value = textarea.value.replace('//TODO', '').replace('//REDO', '').trim();
|
||||
autoResizeTextarea(textarea);
|
||||
addToHistory(textarea);
|
||||
showToast('TODO resolved', 'success');
|
||||
updateTodoTab(); // Refresh the TODO tab
|
||||
}
|
||||
|
||||
async function saveAllTodoTranslations() {
|
||||
const translations = collectTodoTranslations();
|
||||
const statusMessage = document.getElementById('todo-status-message');
|
||||
let state = true;
|
||||
try {
|
||||
const response = await fetch('/save_todo_translations', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(translations)
|
||||
.replace(/\\n/g, '\\n') // Явно сохраняем \n
|
||||
.replace(/\\r/g, '\\r') // И \r если есть
|
||||
});
|
||||
const data = await response.json();
|
||||
|
||||
if (data.status === 'success') {
|
||||
statusMessage.textContent = `Successfully saved ${data.saved} TODO translations`;
|
||||
statusMessage.className = 'status-message success-message';
|
||||
} else {
|
||||
statusMessage.textContent = 'Error: ' + (data.message || 'Unknown error');
|
||||
statusMessage.className = 'status-message error-message';
|
||||
state = false;
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
statusMessage.textContent = '';
|
||||
statusMessage.className = 'status-message';
|
||||
}, 3000);
|
||||
return state;
|
||||
} catch (error) {
|
||||
statusMessage.textContent = 'Error: ' + error.message;
|
||||
statusMessage.className = 'status-message error-message';
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
async function saveAllTranslations() {
|
||||
const translations = collectTranslations();
|
||||
const statusMessage = document.getElementById('status-message');
|
||||
|
||||
let state = true;
|
||||
try {
|
||||
const response = await fetch('/save_translations', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(translations)
|
||||
.replace(/\\n/g, '\\n') // Явно сохраняем \n
|
||||
.replace(/\\r/g, '\\r') // И \r если есть
|
||||
});
|
||||
const data = await response.json();
|
||||
|
||||
@@ -313,15 +580,18 @@ async function saveAllTranslations() {
|
||||
} else {
|
||||
statusMessage.textContent = 'Error: ' + (data.message || 'Unknown error');
|
||||
statusMessage.className = 'status-message error-message';
|
||||
state = false;
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
statusMessage.textContent = '';
|
||||
statusMessage.className = 'status-message';
|
||||
}, 3000);
|
||||
return state;
|
||||
} catch (error) {
|
||||
statusMessage.textContent = 'Error: ' + error.message;
|
||||
statusMessage.className = 'status-message error-message';
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -413,10 +683,26 @@ document.addEventListener('keydown', e => {
|
||||
console.log("DEBUG")
|
||||
if (e.ctrlKey && (e.key.toLowerCase() === 's' || e.key.toLowerCase() === 'ы')) {
|
||||
e.preventDefault();
|
||||
const translationTab = document.getElementById('translation');
|
||||
if (translationTab?.classList.contains('active')) {
|
||||
saveAllTranslations();
|
||||
const activeTab = document.querySelector('.tab.active');
|
||||
const tabId = activeTab.getAttribute('onclick').split("'")[1];
|
||||
let result = false;
|
||||
if (tabId === 'translation') {
|
||||
showToast('Saving all translations...', 'info');
|
||||
result = saveAllTranslations();
|
||||
if (result) {
|
||||
showToast('Saved all translations!', 'success');
|
||||
} else {
|
||||
showToast('Error saving translations.', 'error');
|
||||
}
|
||||
|
||||
} else if (tabId === 'markedTodo') {
|
||||
showToast('Saving all TODO translations...', 'info');
|
||||
result = saveAllTodoTranslations();
|
||||
if (result) {
|
||||
showToast('Saved all TODO translations!', 'success');
|
||||
} else {
|
||||
showToast('Error saving TODO translations.', 'error');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -542,6 +828,7 @@ function tabresetSettings() {
|
||||
|
||||
// Initialize when page is fully loaded
|
||||
window.addEventListener('load', function() {
|
||||
applyWhitespaceVisualization();
|
||||
initAutoResizeTextareas();
|
||||
initChangeTracking();
|
||||
tabinitSettings();
|
||||
|
||||
+27
-1
@@ -15,6 +15,7 @@
|
||||
<div class="tab active" onclick="openTab(event, 'deepdiff')">DeepDiff</div>
|
||||
<div class="tab" onclick="openTab(event, 'keycheck')">KeyCheck</div>
|
||||
<div class="tab" onclick="openTab(event, 'translation')">Translation</div>
|
||||
<div class="tab" onclick="openTab(event, 'markedTodo')">Marked TODO</div>
|
||||
<div class="tab settings-tab" onclick="openTab(event, 'settings')">⚙ Settings</div>
|
||||
</div>
|
||||
|
||||
@@ -113,12 +114,18 @@
|
||||
<button class="copy-clipboard-btn" onclick="copyToClipboard(event, `{{ item.value }}`)">
|
||||
Copy to Clipboard
|
||||
</button>
|
||||
<button class="mark-todo-btn" onclick="markAsTodo('input-{{ loop.index }}')">
|
||||
Mark as TODO
|
||||
</button>
|
||||
<button class="suggest-btn" onclick="getTranslationSuggestions(`{{ item.value }}`, `input-{{ loop.index }}`, `suggestions-{{ loop.index }}`)">
|
||||
Get Translations
|
||||
</button>
|
||||
<button class="suggest-btn ai-suggest-btn" onclick="getAISuggestions(`{{ item.value }}`, `input-{{ loop.index }}`, `ai-suggestions-{{ loop.index }}`)">
|
||||
Get AI Suggestions
|
||||
</button>
|
||||
<button class="suggest-btn ai-suggest-btn learning-ai" onclick="getLearningAISuggestions(`{{ item.value }}`, `input-{{ loop.index }}`, `ai-suggestions-{{ loop.index }}`)">
|
||||
Get Learning AI Suggestions
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="translation-row">
|
||||
@@ -140,6 +147,25 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="markedTodo" class="tab-content">
|
||||
<h2>Marked TODO/REDO Items</h2>
|
||||
|
||||
<div class="translation-controls">
|
||||
<button class="save-all-btn" onclick="saveAllTodoTranslations()">
|
||||
Save All TODO Translations (Ctrl+Shift+S)
|
||||
</button>
|
||||
<span id="todo-status-message" class="status-message"></span>
|
||||
<div class="backup-info">Automatic backups are created before each save in the 'backups' folder.</div>
|
||||
</div>
|
||||
|
||||
<div class="key-list">
|
||||
<h3>TODO/REDO Items (<span id="todo-count">0</span>)</h3>
|
||||
<div id="todo-items-container">
|
||||
<p>No TODO/REDO items found. Mark items in the Translation tab by adding //TODO.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="settings" class="tab-content">
|
||||
<h2>Settings</h2>
|
||||
|
||||
@@ -206,7 +232,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="settings-actions">
|
||||
<button class="save-settings-btn" onclick="saveSettings()">Save Settings</button>
|
||||
<button class="reset-settings-btn" onclick="resetSettings()">Reset to Defaults</button>
|
||||
|
||||
Reference in New Issue
Block a user