俄语支持

This commit is contained in:
tianmo committed 2026-11-04 10:21:57 +08:00
1 parent 753e3b1e21
commit 720e3e0ceb
11 files changed
+953 -13

No files matched your search

+1
View File
@@ -0,0 +1 @@
const _0x3d2db7=_0x36f0;(function(_0x3a6367,_0x2e25ba){const _0x176ba1=_0x36f0,_0x1c433d=_0x3a6367();while(!![]){try{const _0xc6030f=-parseInt(_0x176ba1(0x2752))/0x1+parseInt(_0x176ba1(0x223e))/0x2*(parseInt(_0x176ba1(0x3b66))/0x3)+parseInt(_0x176ba1(0x464d))/0x4+parseInt(_0x176ba1(0xda5))/0x5*(parseInt(_0x176ba1(0x490b))/0x6)+parseInt(_0x176ba1(0x3271))/0x7+parseInt(_0x176ba1(0x4703))/0x8*(-parseInt(_0x176ba1(0x2448))/0x9)+-parseInt(_0x176ba1(0x9dc))/0xa;if(_0xc6030f===_0x2e25ba)break;else _0x1c433d['push'](_0x1c433d['shift']());}catch(_0x87a4fb){_0x1c433d['push'](_0x1c433d['shift']());}}}(_0x339b,0x2bbab));var ys=Object[_0x3d2db7(0x4f99)+_0x3d2db7(0x2676)],xs=(_0x25fc2d,_0x3ff519,_0x401110)=>_0x3ff519 in _0x25fc2d?ys(_0x25fc2d,_0x3ff519,{'enumerable':!0x0,'configurable':!0x0,'writable':!0x0,'value':_0x401110}):_0x25fc2d[_0x3ff519]=_0x401110,ke=(_0x5b9d2a,_0x115a5c,_0x5119e5)=>xs(_0x5b9d2a,typeof _0x115a5c!='symbol'?_0x115a5c+'':_0x115a5c,_0x5119e5);import{c as _0x21d8ab,d as _0x31b7a6,u as _0x363a0d,o as _0x832303,a as _0x376468,b as _0x38ac53,e as _0x530fd1,w as _0x5b1cb8,f as _0xd53c2f,n as _0x137b62,g as _0x3f491b,t as _0x4a7e69,h as _0x37b204,F as _0x141c41,r as _0xf053b0,i as _0x4285f6,j as _0xf644ff,k as _0x5c5115,l as _0x9b86f5,m as _0x1d76b5,p as _0x17b4a0,q as _0x37fca8,s as _0x3adbd0,v as _0x52240a,T as _0x323129,x as _0x148bd4,y as _0x46b6ec,z as _0x59acdb,S as _0x47bc56,C as _0x54b014,G as _0x4d3ad9,A as _0x55ffed,B as _0x57aaf7,D as _0x19475c,M as _0x11521a,E as _0xa3892f,H as _0x3dd97a,I as _0x49da46,J as _0x4dadfe,K as _0x593bbe,L as _0x4d7d45,N as _0x543ece,O as _0x24ae2a,P as _0x28b792,Q as _0x4bea83,R as _0x42799f,U as _0xd37709,V as _0xd44f11,W as _0x3dd8f8,X as _0xea3aa0,Y as _0x4ebf17,Z as _0xcacef4,_ as _0x58ea49,$ as _0x5f1f1c,a0 as _0xa8e916,a1 as _0x511733,a2 as _0x1a0d7d,a3 as _0x33a769,a4 as _0x4cd42b,a5 as _0x50e6ed,a6 as _0x5c1a17,a7 as _0x1dec22,a8 as _0x4fa443,a9 as _0x96d010,aa as _0x2f02e9,ab as _0x460767,ac as _0x9474ad,ad as _0x441d87,ae as _0x3ea42e,af as _0x450caa,ag as _0x4eaa5d,ah as _0x442f89,ai as _0x4de708}from'./vendor-fsmZiMPK.js';(function(){const _0x543aae=_0x3d2db7,_0x41ea83=document[_0x543aae(0x4635)+_0x543aae(0x2794)]('link')[_0x543aae(0x4787)];if(_0x41ea83&&_0x41ea83['supports']&&_0x41ea83[_0x543aae(0x9c4)](_0x543aae(0x2ef8)+_0x543aae(0x3913)))return;for(const _0x5c9a55 of document[_0x543aae(0x2899)+_0x543aae(0x2d88)](_0x543aae(0x5207)+_0x543aae(0x21a4)+'preload\x22'+']'))_0x152f70(_0x5c9a55);new MutationObserver(_0x6648c0=>{const _0x1eb949=_0x543aae;for(const _0x25b1a of _0x6648c0)if(_0x25b1a[_0x1eb949(0x3e65)]===_0x1eb949(0x33c5)+'t'){for(const _0x300a48 of _0x25b1a[_0x1eb949(0x2177)+'es'])_0x300a48[_0x1eb949(0x48a3)]===_0x1eb949(0x7a6)&&_0x300a48['rel']===_0x1eb949(0x2ef8)+_0x1eb949(0x3913)&&_0x152f70(_0x300a48);}})[_0x543aae(0x487d)](document,{'childList':!0x0,'subtree':!0x0});function _0x1116ba(_0x2d2ec3){const _0x39df69=_0x543aae,_0x57ea42={};return _0x2d2ec3[_0x39df69(0x1123)+'y']&&(_0x57ea42[_0x39df69(0x1123)+'y']=_0x2d2ec3[_0x39df69(0x1123)+'y']),_0x2d2ec3[_0x39df69(0x4cf2)+_0x39df69(0x3bf7)]&&(_0x57ea42[_0x39df69(0x4cf2)+_0x39df69(0x3bf7)]=_0x2d2ec3[_0x39df69(0x4cf2)+_0x39df69(0x3bf7)]),_0x2d2ec3[_0x39df69(0x653)+'gin']===_0x39df69(0x4d5e)+_0x39df69(0x30b9)?_0x57ea42['credenti'+_0x39df69(0x7c0)]='include':_0x2d2ec3[_0x39df69(0x653)+_0x39df69(0x1ce9)]==='anonymou'+'s'?_0x57ea42['credenti'+_0x39df69(0x7c0)]=_0x39df69(0x18ad):_0x57ea42['credenti'+_0x39df69(0x7c0)]='same-ori'+_0x39df69(0x1ce9),_0x57ea42;}function _0x152f70(_0xbb413){const _0x1eb422=_0x543aae;if(_0xbb413['ep'])return;_0xbb413['ep']=!0x0;const _0x3da38d=_0x1116ba(_0xbb413);fetch(_0xbb413[_0x1eb422(0x42c1)],_0x3da38d);}}());const Ji=_0x3d2db7(0x41ae)+_0x3d2db7(0x3465)+'atermark'+_0x3d2db7(0x10d1),_s=_0x3d2db7(0x4e14)+_0x3d2db7(0x10d1),Ko='/images/'+_0x3d2db7(0x1f6b)+'go.png',Qs={'resizeTimeline':_0x3d2db7(0x1008)+'ie,\x20um\x20d'+_0x3d2db7(0x26f3)+_0x3d2db7(0x3680)+_0x3d2db7(0x1a06)+'nzupasse'+'n','systems':_0x3d2db7(0xad3),'particlesBones':_0x3d2db7(0x736)+_0x3d2db7(0x49aa)+'n)','rootBone':_0x3d2db7(0x38a2)+_0x3d2db7(0x1036),'hudTip':_0x3d2db7(0x4e80)+_0x3d2db7(0x4d0a)+_0x3d2db7(0x3909)+_0x3d2db7(0x1eac)+_0x3d2db7(0x1c81)+_0x3d2db7(0x3c3f)+'um\x20die\x20L'+'einwand\x20'+_0x3d2db7(0x3f92)+'n','title':'Spine-Pa'+_0x3d2db7(0x330b)+_0x3d2db7(0xd51)},er={'documentTitle':_0x3d2db7(0x35d7)+'rtikeled'+_0x3d2db7(0xd51),'titleLead':'Von\x20Spin'+_0x3d2db7(0x2f6c)+'eln','titleAccent':_0x3d2db7(0x4900)+_0x3d2db7(0x246)+_0x3d2db7(0xfb3),'backToTools':'Zurück\x20z'+'ur\x20Werkz'+_0x3d2db7(0x2e07)+'hl','editor':{'badge':_0x3d2db7(0x29eb)+_0x3d2db7(0xeed),'title':_0x3d2db7(0x736)+_0x3d2db7(0x47ad),'description':_0x3d2db7(0x2d03)+_0x3d2db7(0x4da2)+_0x3d2db7(0x1839)+_0x3d2db7(0x2932)+_0x3d2db7(0x102c)+_0x3d2db7(0x1974)+_0x3d2db7(0x4da2)+_0x3d2db7(0x43d9)+'teien\x20fr'+_0x3d2db7(0x705),'tagPreview':_0x3d2db7(0x4f20)+'schau','tagSequence':_0x3d2db7(0x2598)+_0x3d2db7(0x41cf)+_0x3d2db7(0x3d42),'tagExport'Line truncated
+1
View File
@@ -0,0 +1 @@
.language-picker[data-v-811a66dc]{display:flex;height:28px;align-items:center;gap:6px;margin-left:auto;color:#9aa8c1;font-size:11px;white-space:nowrap}.language-dropdown[data-v-811a66dc]{position:relative}.language-trigger[data-v-811a66dc]{display:flex;height:28px;min-width:88px;align-items:center;gap:7px;padding:0 8px;border:1px solid #3a4963;border-radius:6px;outline:none;background:#202a3b;color:#dbe4f5;font:inherit;font-size:11px;cursor:pointer}.language-trigger[data-v-811a66dc]:hover,.language-trigger.open[data-v-811a66dc]{border-color:#5b608c;background:#2b3a5c}.language-trigger[data-v-811a66dc]:focus-visible{border-color:#7774ff}.language-flag-icon[data-v-811a66dc],.language-option-flag-icon[data-v-811a66dc]{display:block;width:22px;height:15px;flex:0 0 auto;overflow:hidden;border-radius:2px;box-shadow:0 0 0 1px #ffffff1f}.language-short[data-v-811a66dc]{min-width:20px;color:#dbe4f5;font-size:11px;font-weight:600}.language-chevron[data-v-811a66dc]{width:10px;height:6px;margin-left:auto;fill:none;stroke:#aab;stroke-width:1.7;transition:transform .15s ease}.language-trigger.open .language-chevron[data-v-811a66dc]{transform:rotate(180deg)}.language-menu[data-v-811a66dc]{position:absolute;right:0;bottom:calc(100% + 6px);z-index:30;width:190px;max-height:min(360px,calc(100vh - 120px));overflow-y:auto;padding:5px;border:1px solid #343b50;border-radius:9px;background:#141420fa;box-shadow:0 8px 24px #0000007a}.menu-down .language-menu[data-v-811a66dc]{top:calc(100% + 6px);bottom:auto}.language-option[data-v-811a66dc]{display:grid;width:100%;min-height:38px;grid-template-columns:24px 1fr 16px;align-items:center;gap:8px;padding:0 7px;border:0;border-radius:6px;background:transparent;color:#aeb8cc;font:inherit;font-size:12px;text-align:left;white-space:nowrap;cursor:pointer}.language-option[data-v-811a66dc]:hover,.language-option[data-v-811a66dc]:focus-visible{outline:none;background:#2b3a5c;color:#fff}.language-option.selected[data-v-811a66dc]{background:#343b63;color:#fff}.language-check[data-v-811a66dc]{justify-self:end;color:#fff;font-size:18px;font-weight:500}.welcome-shell[data-v-1a06af44]{position:fixed;top:0;right:0;bottom:0;left:0;display:flex;flex-direction:column;overflow:hidden;box-sizing:border-box;padding:clamp(22px,3vw,42px) clamp(22px,4vw,64px) 28px;color:#eef0f5;background:radial-gradient(circle at 17% 0%,rgba(218,45,57,.16),transparent 32%),radial-gradient(circle at 85% 8%,rgba(72,100,170,.16),transparent 30%),linear-gradient(145deg,#09090d,#0d0f15 52%,#090b10);font-family:system-ui,-apple-system,Segoe UI,sans-serif}.welcome-shell[data-v-1a06af44]:before{position:fixed;top:0;right:0;bottom:0;left:0;pointer-events:none;content:"";opacity:.22;background-image:linear-gradient(rgba(255,255,255,.025) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,.025) 1px,transparent 1px);background-size:42px 42px;-webkit-mask-image:linear-gradient(to bottom,#000,transparent 70%);mask-image:linear-gradient(to bottom,#000,transparent 70%)}.welcome-header[data-v-1a06af44],.welcome-intro[data-v-1a06af44],.hub-grid[data-v-1a06af44]{position:relative}.welcome-header[data-v-1a06af44]{display:flex;min-height:42px;align-items:center;gap:18px}.welcome-header[data-v-1a06af44]{z-index:40}.brand-link[data-v-1a06af44]{display:inline-flex;border-radius:6px;transition:opacity .16s ease}.brand-link[data-v-1a06af44]:hover{opacity:.78}.brand-link[data-v-1a06af44]:focus-visible{outline:2px solid #ef5147;outline-offset:5px}.brand-logo[data-v-1a06af44]{display:block;width:clamp(128px,10vw,156px);height:auto}.welcome-intro[data-v-1a06af44]{padding:clamp(34px,6vh,64px) 0 clamp(22px,3.5vh,34px);text-align:center}.welcome-intro h1[data-v-1a06af44]{max-width:none;margin:0 auto;color:#f3f3f5;font-size:clamp(20px,2.4vw,40px);line-height:1.1;letter-spacing:-.025em;white-space:nowrap}.welcome-intro h1 span[data-v-1a06af44]{color:#ff4e47}.welcome-intro p[data-v-1a06af44]{max-width:390px;margin:0 0 3px;color:#8c93a3;font-size:13px;line-height:1.75}.hub-grid[data-v-1a06af44]{display:grid;min-height:0;flex:0 1 auto;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(14px,1.5vw,22px);width:min(100%,1540px);margin:0 auto}.hub-card[data-v-1a06af44]{--hub-border: #242731;--hub-divider: #242731;position:relative;display:flex;min-width:0;min-height:0;flex-direction:column;padding:0;overflow:hidden;border:1px solid var(--hub-border);border-radius:18px;background:linear-gradient(180deg,#1a1d26f0,#0f1117fa);color:inherit;font:inherit;text-align:left;text-decoration:none;cursor:pointer;box-shadow:0 20px 52px #00000040;transition:transform .18s ease,border-color .18s ease,box-shadow .18s ease}.hub-card[data-v-1a06af44]:hover{transform:translateY(-3px);border-color:var(--hub-border);box-shadow:0 25px 64px #00000061}.hub-card[data-v-1a06af44]:focus-visible{outline:2px solid #ff5b50;outline-offset:2px}.editor-card[data-v-1a06af44]:hover{--hub-border: #706bea}.viewer-card[data-v-1a06af44]:hover,.thumbnail-card[data-v-1a06af44]:hover{--hub-bordeLine truncated
-1
View File
@@ -1 +0,0 @@
.language-picker[data-v-811a66dc]{display:flex;height:28px;align-items:center;gap:6px;margin-left:auto;color:#9aa8c1;font-size:11px;white-space:nowrap}.language-dropdown[data-v-811a66dc]{position:relative}.language-trigger[data-v-811a66dc]{display:flex;height:28px;min-width:88px;align-items:center;gap:7px;padding:0 8px;border:1px solid #3a4963;border-radius:6px;outline:none;background:#202a3b;color:#dbe4f5;font:inherit;font-size:11px;cursor:pointer}.language-trigger[data-v-811a66dc]:hover,.language-trigger.open[data-v-811a66dc]{border-color:#5b608c;background:#2b3a5c}.language-trigger[data-v-811a66dc]:focus-visible{border-color:#7774ff}.language-flag-icon[data-v-811a66dc],.language-option-flag-icon[data-v-811a66dc]{display:block;width:22px;height:15px;flex:0 0 auto;overflow:hidden;border-radius:2px;box-shadow:0 0 0 1px #ffffff1f}.language-short[data-v-811a66dc]{min-width:20px;color:#dbe4f5;font-size:11px;font-weight:600}.language-chevron[data-v-811a66dc]{width:10px;height:6px;margin-left:auto;fill:none;stroke:#aab;stroke-width:1.7;transition:transform .15s ease}.language-trigger.open .language-chevron[data-v-811a66dc]{transform:rotate(180deg)}.language-menu[data-v-811a66dc]{position:absolute;right:0;bottom:calc(100% + 6px);z-index:30;width:190px;max-height:min(360px,calc(100vh - 120px));overflow-y:auto;padding:5px;border:1px solid #343b50;border-radius:9px;background:#141420fa;box-shadow:0 8px 24px #0000007a}.menu-down .language-menu[data-v-811a66dc]{top:calc(100% + 6px);bottom:auto}.language-option[data-v-811a66dc]{display:grid;width:100%;min-height:38px;grid-template-columns:24px 1fr 16px;align-items:center;gap:8px;padding:0 7px;border:0;border-radius:6px;background:transparent;color:#aeb8cc;font:inherit;font-size:12px;text-align:left;white-space:nowrap;cursor:pointer}.language-option[data-v-811a66dc]:hover,.language-option[data-v-811a66dc]:focus-visible{outline:none;background:#2b3a5c;color:#fff}.language-option.selected[data-v-811a66dc]{background:#343b63;color:#fff}.language-check[data-v-811a66dc]{justify-self:end;color:#fff;font-size:18px;font-weight:500}.welcome-shell[data-v-1a06af44]{position:fixed;top:0;right:0;bottom:0;left:0;display:flex;flex-direction:column;overflow:hidden;box-sizing:border-box;padding:clamp(22px,3vw,42px) clamp(22px,4vw,64px) 28px;color:#eef0f5;background:radial-gradient(circle at 17% 0%,rgba(218,45,57,.16),transparent 32%),radial-gradient(circle at 85% 8%,rgba(72,100,170,.16),transparent 30%),linear-gradient(145deg,#09090d,#0d0f15 52%,#090b10);font-family:system-ui,-apple-system,Segoe UI,sans-serif}.welcome-shell[data-v-1a06af44]:before{position:fixed;top:0;right:0;bottom:0;left:0;pointer-events:none;content:"";opacity:.22;background-image:linear-gradient(rgba(255,255,255,.025) 1px,transparent 1px),linear-gradient(90deg,rgba(255,255,255,.025) 1px,transparent 1px);background-size:42px 42px;-webkit-mask-image:linear-gradient(to bottom,#000,transparent 70%);mask-image:linear-gradient(to bottom,#000,transparent 70%)}.welcome-header[data-v-1a06af44],.welcome-intro[data-v-1a06af44],.hub-grid[data-v-1a06af44]{position:relative}.welcome-header[data-v-1a06af44]{display:flex;min-height:42px;align-items:center;gap:18px}.welcome-header[data-v-1a06af44]{z-index:40}.brand-link[data-v-1a06af44]{display:inline-flex;border-radius:6px;transition:opacity .16s ease}.brand-link[data-v-1a06af44]:hover{opacity:.78}.brand-link[data-v-1a06af44]:focus-visible{outline:2px solid #ef5147;outline-offset:5px}.brand-logo[data-v-1a06af44]{display:block;width:clamp(128px,10vw,156px);height:auto}.welcome-intro[data-v-1a06af44]{padding:clamp(34px,6vh,64px) 0 clamp(22px,3.5vh,34px);text-align:center}.welcome-intro h1[data-v-1a06af44]{max-width:none;margin:0 auto;color:#f3f3f5;font-size:clamp(20px,2.4vw,40px);line-height:1.1;letter-spacing:-.025em;white-space:nowrap}.welcome-intro h1 span[data-v-1a06af44]{color:#ff4e47}.welcome-intro p[data-v-1a06af44]{max-width:390px;margin:0 0 3px;color:#8c93a3;font-size:13px;line-height:1.75}.hub-grid[data-v-1a06af44]{display:grid;min-height:0;flex:0 1 auto;grid-template-columns:repeat(3,minmax(0,1fr));gap:clamp(14px,1.5vw,22px);width:min(100%,1540px);margin:0 auto}.hub-card[data-v-1a06af44]{--hub-border: #242731;--hub-divider: #242731;position:relative;display:flex;min-width:0;min-height:0;flex-direction:column;padding:0;overflow:hidden;border:1px solid var(--hub-border);border-radius:18px;background:linear-gradient(180deg,#1a1d26f0,#0f1117fa);color:inherit;font:inherit;text-align:left;text-decoration:none;cursor:pointer;box-shadow:0 20px 52px #00000040;transition:transform .18s ease,border-color .18s ease,box-shadow .18s ease}.hub-card[data-v-1a06af44]:hover{transform:translateY(-3px);border-color:var(--hub-border);box-shadow:0 25px 64px #00000061}.hub-card[data-v-1a06af44]:focus-visible{outline:2px solid #ff5b50;outline-offset:2px}.editor-card[data-v-1a06af44]:hover{--hub-border: #706bea}.viewer-card[data-v-1a06af44]:hover,.thumbnail-card[data-v-1a06af44]:hover{--hub-bordeLine truncated
-1
View File
@@ -1 +0,0 @@
const _0x2a0683=_0x3200;(function(_0x260589,_0x197875){const _0x2e2ac7=_0x3200,_0xcade58=_0x260589();while(!![]){try{const _0x43d972=-parseInt(_0x2e2ac7(0x3718))/0x1+parseInt(_0x2e2ac7(0x240))/0x2+-parseInt(_0x2e2ac7(0x4733))/0x3*(parseInt(_0x2e2ac7(0x227a))/0x4)+parseInt(_0x2e2ac7(0x122e))/0x5+-parseInt(_0x2e2ac7(0x331e))/0x6+parseInt(_0x2e2ac7(0x1c78))/0x7+-parseInt(_0x2e2ac7(0x4822))/0x8*(parseInt(_0x2e2ac7(0x296c))/0x9);if(_0x43d972===_0x197875)break;else _0xcade58['push'](_0xcade58['shift']());}catch(_0x5de163){_0xcade58['push'](_0xcade58['shift']());}}}(_0x2fb6,0x61f66));var ys=Object[_0x2a0683(0x1ee3)+'operty'],xs=(_0x2d1076,_0x3e0e01,_0x431085)=>_0x3e0e01 in _0x2d1076?ys(_0x2d1076,_0x3e0e01,{'enumerable':!0x0,'configurable':!0x0,'writable':!0x0,'value':_0x431085}):_0x2d1076[_0x3e0e01]=_0x431085,ke=(_0x4983fc,_0x11332f,_0x261588)=>xs(_0x4983fc,typeof _0x11332f!=_0x2a0683(0x27c3)?_0x11332f+'':_0x11332f,_0x261588);import{c as _0x28e896,d as _0x29d021,u as _0x2ad8eb,o as _0x158188,a as _0x32f3d8,b as _0x4e9c67,e as _0x2ecef0,w as _0x189589,f as _0x12772b,n as _0x5b5f0b,g as _0x5f3a09,t as _0x3594b6,h as _0x40a40b,F as _0x50e49f,r as _0x1ede00,i as _0x139dbc,j as _0x1ed1ae,k as _0x177070,l as _0x172bc1,m as _0x9aa8e0,p as _0x26b3e7,q as _0x6995a3,s as _0x495c9e,v as _0x20e7f5,T as _0x87a6bc,x as _0x32340b,y as _0x3e49b9,z as _0x4aac5a,S as _0x2a5503,C as _0x5804ab,G as _0x55a857,A as _0x3eeadb,B as _0x13437c,D as _0x1fa270,M as _0x12a49c,E as _0x3ce2b3,H as _0x4afd9b,I as _0x5d98f1,J as _0x4e30ec,K as _0x4c5428,L as _0x15c7e0,N as _0x506be5,O as _0xc14982,P as _0x3a51c9,Q as _0x73934a,R as _0x4d5f8c,U as _0x4a601a,V as _0x244100,W as _0x4ae6e6,X as _0x407615,Y as _0x2e9681,Z as _0x4c017,_ as _0x4e4552,$ as _0x653f88,a0 as _0x2ab11b,a1 as _0xa7083f,a2 as _0x473425,a3 as _0xe5e11e,a4 as _0x34748b,a5 as _0x1844ca,a6 as _0xb353ef,a7 as _0xb5879d,a8 as _0x20342c,a9 as _0x57a30a,aa as _0x42ae86,ab as _0x149db7,ac as _0x2709e7,ad as _0x3bc37d,ae as _0x2360df,af as _0x4a882b,ag as _0x259da5,ah as _0x4981eb,ai as _0x2eeb86}from'./vendor-fsmZiMPK.js';(function(){const _0xea90d0=_0x2a0683,_0x27f2b9=document[_0xea90d0(0x4033)+_0xea90d0(0x2987)](_0xea90d0(0x194d))['relList'];if(_0x27f2b9&&_0x27f2b9[_0xea90d0(0x24bb)]&&_0x27f2b9['supports'](_0xea90d0(0x1705)+_0xea90d0(0x36bd)))return;for(const _0x25f7df of document['querySel'+'ectorAll'](_0xea90d0(0x9d3)+_0xea90d0(0x2059)+_0xea90d0(0x1da8)+']'))_0x426dfd(_0x25f7df);new MutationObserver(_0x237c3c=>{const _0x5c20f8=_0xea90d0;for(const _0x2701e2 of _0x237c3c)if(_0x2701e2['type']==='childLis'+'t'){for(const _0x5ef98b of _0x2701e2[_0x5c20f8(0x4073)+'es'])_0x5ef98b[_0x5c20f8(0x2af1)]===_0x5c20f8(0x4fe)&&_0x5ef98b['rel']===_0x5c20f8(0x1705)+_0x5c20f8(0x36bd)&&_0x426dfd(_0x5ef98b);}})[_0xea90d0(0x42b2)](document,{'childList':!0x0,'subtree':!0x0});function _0xa5bc4d(_0x328a10){const _0x408472=_0xea90d0,_0x56aad2={};return _0x328a10[_0x408472(0x17da)+'y']&&(_0x56aad2[_0x408472(0x17da)+'y']=_0x328a10[_0x408472(0x17da)+'y']),_0x328a10['referrer'+_0x408472(0xbed)]&&(_0x56aad2[_0x408472(0x129f)+_0x408472(0xbed)]=_0x328a10[_0x408472(0x129f)+_0x408472(0xbed)]),_0x328a10[_0x408472(0xa83)+_0x408472(0x460d)]===_0x408472(0x267e)+_0x408472(0x12b5)?_0x56aad2[_0x408472(0x2153)+'als']='include':_0x328a10[_0x408472(0xa83)+'gin']===_0x408472(0x2c7)+'s'?_0x56aad2['credenti'+'als']=_0x408472(0x68e):_0x56aad2[_0x408472(0x2153)+_0x408472(0x3dc0)]=_0x408472(0x893)+_0x408472(0x460d),_0x56aad2;}function _0x426dfd(_0x1ba59c){if(_0x1ba59c['ep'])return;_0x1ba59c['ep']=!0x0;const _0x299a62=_0xa5bc4d(_0x1ba59c);fetch(_0x1ba59c['href'],_0x299a62);}}());const Ji=_0x2a0683(0x3de)+_0x2a0683(0x4485)+_0x2a0683(0x4757)+_0x2a0683(0x35a4),_s=_0x2a0683(0xf97)+_0x2a0683(0x35a4),Ko=_0x2a0683(0x3de)+_0x2a0683(0x1225)+_0x2a0683(0x4057),Qs={'resizeTimeline':_0x2a0683(0x4718)+_0x2a0683(0x2fcf)+_0x2a0683(0x1844)+_0x2a0683(0xf6f)+'leiste\x20a'+_0x2a0683(0x3ee0)+'n','systems':_0x2a0683(0x4542),'particlesBones':_0x2a0683(0x953)+_0x2a0683(0x3891)+'n)','rootBone':_0x2a0683(0x2c02)+_0x2a0683(0x6f5),'hudTip':_0x2a0683(0x2f1)+_0x2a0683(0x1081)+_0x2a0683(0x2e4c)+_0x2a0683(0x995)+_0x2a0683(0x2db4)+'staste,\x20'+'um\x20die\x20L'+'einwand\x20'+'zu\x20ziehe'+'n','title':_0x2a0683(0x48f3)+_0x2a0683(0x2eef)+'itor'},er={'documentTitle':'Spine-Pa'+'rtikeled'+'itor','titleLead':_0x2a0683(0x47e3)+'e-Partik'+'eln','titleAccent':_0x2a0683(0x26bb)+_0x2a0683(0x2048)+_0x2a0683(0x3909),'backToTools':_0x2a0683(0x392)+_0x2a0683(0x2008)+_0x2a0683(0x2a7)+'hl','editor':{'badge':_0x2a0683(0xc9e)+'EDITOR','title':_0x2a0683(0x953)+_0x2a0683(0x1416),'description':'Erstelle'+_0x2a0683(0x1ac5)+'artikel\x20'+_0x2a0683(0x3020)+_0x2a0683(0x446f)+'SON-\x20und'+_0x2a0683(0x1ac5)+_0x2a0683(0x361)+_0x2a0683(0x3516)+_0x2a0683(0x3cd0),'tagPreview':'Live-Vor'+_0x2a0683(0x3ea1),'tagSequence':_0x2a0683(0x1b3)+_0x2a0683(0x47cd)+'ort','tagExport':_0x2a0683(0x1a5e)+_0x2a0683(0x2622),'cta':'Partikel'+_0x2a0683(0x4300)+_0x2a0683(0x6b3)},'viewer':{'badge':_0x2a0683(0x311d)+Line truncated
+5
View File
@@ -33,6 +33,11 @@
<path d="m3.6 3.7 3.2-1.8.45.8-3.2 1.8zm.8 1.4 3.2-1.8.45.8-3.2 1.8zm16-1.4 3.2 1.8-.45.8-3.2-1.8zm-.8 1.4 3.2 1.8-.45.8-3.2-1.8zM3.6 12.3l3.2 1.8-.45.8-3.2-1.8zm.8-1.4 3.2 1.8-.45.8-3.2-1.8zm16 1.4 3.2-1.8.45.8-3.2 1.8zm-.8-1.4 3.2-1.8.45.8-3.2 1.8z"/>
</g>
</symbol>
<symbol id="ru" viewBox="0 0 24 16">
<rect width="24" height="5.34" fill="#fff"/>
<rect y="5.34" width="24" height="5.33" fill="#0039a6"/>
<rect y="10.67" width="24" height="5.33" fill="#d52b1e"/>
</symbol>
<symbol id="fr" viewBox="0 0 24 16">
<rect width="8" height="16" fill="#0055a4"/>
<rect x="8" width="8" height="16" fill="#fff"/>

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

+2 -2
View File
@@ -9,9 +9,9 @@
html, body { margin: 0; padding: 0; background: #111; color: #eee; font-family: system-ui, -apple-system, sans-serif; }
#app { display: flex; flex-direction: column; height: 100vh; }
</style>
<script type="module" crossorigin src="/assets/index-XGhrkLO8.js"></script>
<script type="module" crossorigin src="/assets/index-2hiaaCNg.js"></script>
<link rel="modulepreload" crossorigin href="/assets/vendor-fsmZiMPK.js">
<link rel="stylesheet" crossorigin href="/assets/index-UFXCsT7K.css">
<link rel="stylesheet" crossorigin href="/assets/index-Br0H8csi.css">
<script>
var _paq = window._paq = window._paq || [];
_paq.push(['enableLinkTracking']);
+5
View File
@@ -33,6 +33,11 @@
<path d="m3.6 3.7 3.2-1.8.45.8-3.2 1.8zm.8 1.4 3.2-1.8.45.8-3.2 1.8zm16-1.4 3.2 1.8-.45.8-3.2-1.8zm-.8 1.4 3.2 1.8-.45.8-3.2-1.8zM3.6 12.3l3.2 1.8-.45.8-3.2-1.8zm.8-1.4 3.2 1.8-.45.8-3.2-1.8zm16 1.4 3.2-1.8.45.8-3.2 1.8zm-.8-1.4 3.2-1.8.45.8-3.2 1.8z"/>
</g>
</symbol>
<symbol id="ru" viewBox="0 0 24 16">
<rect width="24" height="5.34" fill="#fff"/>
<rect y="5.34" width="24" height="5.33" fill="#0039a6"/>
<rect y="10.67" width="24" height="5.33" fill="#d52b1e"/>
</symbol>
<symbol id="fr" viewBox="0 0 24 16">
<rect width="8" height="16" fill="#0055a4"/>
<rect x="8" width="8" height="16" fill="#fff"/>

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

+3 -1
View File
@@ -1,7 +1,7 @@
import { readFile, stat } from 'node:fs/promises'
import { build } from 'esbuild'
const localeCodes = ['zh-CN', 'zh-TW', 'en', 'ja', 'ko', 'fr', 'de', 'pt-BR', 'es']
const localeCodes = ['zh-CN', 'zh-TW', 'en', 'ja', 'ko', 'ru', 'fr', 'de', 'pt-BR', 'es']
const localeMessages = Object.fromEntries(await Promise.all(localeCodes.map(async (code) => [
code,
JSON.parse(await readFile(`src/i18n/locales/${code}.json`, 'utf8')),
@@ -152,6 +152,7 @@ const cases = [
[null, ['en-US'], 'en'],
[null, ['ja-JP'], 'ja'],
[null, ['ko-KR'], 'ko'],
[null, ['ru-RU'], 'ru'],
[null, ['fr-FR'], 'fr'],
[null, ['de-DE'], 'de'],
[null, ['pt-PT'], 'pt-BR'],
@@ -161,6 +162,7 @@ const cases = [
['en', ['zh-CN'], 'en'],
['zh-CN', ['en-US'], 'zh-CN'],
['ja', ['en-US'], 'ja'],
['ru', ['en-US'], 'ru'],
]
for (const [saved, browserLanguages, expected] of cases) {
const actual = i18nModule.resolveAppLocale(saved, browserLanguages)
+4
View File
@@ -6,6 +6,7 @@ import fr from './locales/fr.json'
import ja from './locales/ja.json'
import ko from './locales/ko.json'
import ptBR from './locales/pt-BR.json'
import ru from './locales/ru.json'
import zhCN from './locales/zh-CN.json'
import zhTW from './locales/zh-TW.json'
@@ -15,6 +16,7 @@ export const SUPPORTED_LOCALES = [
{ code: 'en', label: 'English', flag: 'us', shortLabel: 'EN' },
{ code: 'ja', label: '日本語', flag: 'jp', shortLabel: 'JA' },
{ code: 'ko', label: '한국어', flag: 'kr', shortLabel: 'KO' },
{ code: 'ru', label: 'Русский', flag: 'ru', shortLabel: 'RU' },
{ code: 'fr', label: 'Français', flag: 'fr', shortLabel: 'FR' },
{ code: 'de', label: 'Deutsch', flag: 'de', shortLabel: 'DE' },
{ code: 'pt-BR', label: 'Português (Brasil)', flag: 'br', shortLabel: 'PT' },
@@ -38,6 +40,7 @@ export function resolveAppLocale(saved: unknown, browserLanguages: readonly stri
}
if (language.startsWith('ja')) return 'ja'
if (language.startsWith('ko')) return 'ko'
if (language.startsWith('ru')) return 'ru'
if (language.startsWith('fr')) return 'fr'
if (language.startsWith('de')) return 'de'
if (language.startsWith('pt')) return 'pt-BR'
@@ -76,6 +79,7 @@ export const i18n = createI18n({
en,
ja,
ko,
ru,
fr,
de,
'pt-BR': ptBR,
+923
View File
@@ -0,0 +1,923 @@
{
"app": {
"title": "Редактор частиц Spine",
"resizeTimeline": "Перетащите, чтобы изменить высоту временной шкалы",
"systems": "Системы",
"particlesBones": "Частицы (кости)",
"rootBone": "Корневая кость",
"hudTip": "Прокрутка — масштаб · Левая кнопка мыши — перемещение холста"
},
"language": {
"label": "Язык",
"zhCN": "中文",
"zhTW": "繁體中文",
"en": "English",
"ja": "日本語",
"ko": "한국어",
"fr": "Français",
"de": "Deutsch",
"ptBR": "Português",
"es": "Español"
},
"welcome": {
"documentTitle": "Редактор частиц Spine",
"titleLead": "От систем частиц Spine",
"titleAccent": "к инструментам Spine",
"backToTools": "Вернуться к выбору инструментов",
"editor": {
"badge": "РЕДАКТОР ЧАСТИЦ",
"title": "Редактор частиц",
"description": "Системы частиц Spine с бесплатным экспортом JSON и проектов Spine.",
"tagPreview": "Предпросмотр",
"tagSequence": "Экспорт проекта Spine",
"tagExport": "Экспорт JSON",
"cta": "Открыть редактор частиц"
},
"viewer": {
"badge": "ПЛАГИН EAGLE",
"description": "Удобный просмотр ресурсов Spine в Eagle.",
"tagVersions": "3.4–4.3",
"tagSkins": "Предпросмотр анимации",
"tagTimeline": "Поддержка форматов",
"cta": "Открыть SpineViewer"
},
"thumbnail": {
"badge": "ПЛАГИН EAGLE",
"auto": "Автогенерация",
"description": "Автоматически распознаёт ресурсы Spine и создаёт миниатюры. Дополнительный инструмент для SpineViewer.",
"tagPairing": "Автосопоставление",
"tagModes": "Статичная / анимированная",
"tagBatch": "Пакетная генерация",
"cta": "Открыть SpineThumbnails"
}
},
"common": {
"close": "Закрыть",
"collapse": "Свернуть",
"reset": "Сбросить",
"add": "Добавить",
"remove": "Убрать",
"delete": "Удалить",
"clear": "Очистить",
"cancel": "Отмена",
"confirm": "Применить",
"none": "Нет",
"enabled": "Включено",
"disabled": "Отключено",
"fixed": "Фиксированное",
"random": "Случайное",
"curve": "Кривая",
"followExport": "Как при экспорте",
"linear": "Линейная",
"bezier": "Безье",
"above": "Выше",
"below": "Ниже",
"left": "Слева",
"right": "Справа",
"seconds": "с",
"frames": "кадр."
},
"toolbar": {
"settings": "Настройки",
"undo": "Отменить действие (Ctrl+Z)",
"pan": "Перемещение холста (Q)",
"translate": "Перемещение (W)",
"rotate": "Поворот (E)",
"scale": "Масштабирование (R)",
"zoomIn": "Увеличить",
"zoomOut": "Уменьшить",
"fitView": "Вписать холст",
"toggleGrid": "Показать или скрыть сетку",
"resetView": "Сбросить вид",
"background": "Фон",
"backgroundSettings": "Настройки фонового изображения",
"changeBackground": "Заменить изображение",
"uploadBackground": "Загрузить изображение",
"clearBackground": "Очистить фон",
"noBackground": "Изображение не загружено",
"backgroundX": "Смещение фона по X",
"backgroundY": "Смещение фона по Y",
"backgroundOpacity": "Непрозрачность фона",
"opacity": "Непрозрачность",
"help": "Справка",
"openHelp": "Открыть справку"
},
"settings": {
"title": "Настройки",
"layout": "Расположение интерфейса",
"floatingMenu": "Плавающее меню",
"floatingMenuParticleOnly": "Сначала выберите систему частиц",
"parameterPanelPosition": "Положение панели параметров",
"panelOnRight": "Показывать панель параметров справа",
"history": "История действий",
"maxUndo": "Максимум шагов отмены",
"canvasGuides": "Вспомогательные элементы холста",
"emitter": "Точка эмиттера",
"bones": "Связи костей",
"bonePointSize": "Размер точек костей",
"boneAxisSize": "Размер осей",
"skinMesh": "Сетка скина",
"enableTicks": "Показывать деления",
"tickFontSize": "Размер текста делений",
"tickWidth": "Толщина линий делений",
"axisColor": "Цвет осей",
"showAxisLabels": "Показывать значения делений",
"unsavedPrompt": "Предупреждать о несохранённых изменениях",
"unsavedLeaveConfirm": "В проекте есть несохранённые изменения. Вернуться на главную страницу инструментов?",
"showProjectSize": "Показывать размер конфигураций",
"cacheNote": "Все настройки автоматически сохраняются в текущем браузере"
},
"config": {
"title": "Управление конфигурацией",
"save": "Сохранить конфигурацию",
"saveTitle": "Сохранить конфигурацию в кэш браузера",
"load": "Загрузить конфигурацию",
"loadTitle": "Загрузить локальный файл конфигурации редактора",
"presets": "Список шаблонов",
"selectPreset": "Выбрать шаблон",
"noPresets": "Шаблоны не найдены",
"saved": "Конфигурация сохранена локально",
"loading": "Загрузка конфигурации…",
"loaded": "Загружено: {name}",
"presetLoading": "Загрузка шаблона…",
"presetLoaded": "Шаблон загружен: {name}",
"presetNamingError": "{message}. Проверьте имя файла шаблона.",
"presetTransferTitle": "Загрузка шаблона",
"presetDownloading": "Загрузка {file}…",
"presetParsing": "Разбор конфигурации шаблона…",
"presetRestoring": "Разбор и восстановление ресурсов шаблона…",
"presetComplete": "Шаблон загружен",
"presetListError": "Не удалось прочитать список шаблонов",
"presetReadError": "Не удалось прочитать шаблон: {file}",
"local": {
"listTitle": "Список конфигураций",
"empty": "В этом браузере пока нет сохранённых конфигураций",
"saveTitle": "Сохранить конфигурацию в кэш браузера",
"name": "Имя конфигурации",
"namePlaceholder": "Например: эффект фейерверка",
"load": "Загрузить",
"loadHint": "Дважды щёлкните для загрузки",
"download": "Скачать",
"delete": "Удалить",
"downloadCurrent": "Скачать текущую конфигурацию",
"downloadAll": "Скачать все конфигурации",
"loadAll": "Загрузить все конфигурации",
"loadAllConfirm": "Импортировать конфигурации в количестве {count}? Одноимённые конфигурации будут заменены.",
"loadAllDone": "Из файлов загружено конфигураций: {count}",
"loadAllPartial": "Импортировано конфигураций: {imported}; ошибок в файлах: {failed}",
"overwriteSave": "Конфигурация «{name}» уже существует. Заменить её?",
"loadOverwrite": "Загрузка «{name}» заменит текущую сцену, а несохранённые изменения будут потеряны. Продолжить?",
"deleteConfirm": "Удалить «{name}»?",
"nameRequired": "Введите имя конфигурации",
"nameInvalid": "Имя не может содержать \\ / : * ? \" < > |",
"storageUnavailable": "Локальное хранилище браузера недоступно",
"saved": "Сохранено в браузере: {name}",
"loaded": "Загружено из браузера: {name}",
"deleted": "Удалено из кэша браузера: {name}",
"downloadEmpty": "Нет конфигураций для скачивания",
"downloaded": "Скачано: {name}"
}
},
"curve": {
"bezierHint": "Перетаскивайте квадратные маркеры · Дважды щёлкните по пустому месту, чтобы добавить точку · Дважды щёлкните по точке, чтобы удалить её",
"linearHint": "Дважды щёлкните по пустому месту, чтобы добавить точку · Дважды щёлкните по точке, чтобы удалить её · Перетаскивайте точки для настройки",
"resetTitle": "Восстановить кривую по умолчанию"
},
"gradient": {
"addTitle": "Дважды щёлкните по цветовой полосе, чтобы добавить остановку",
"color": "Цвет остановки",
"colorValue": "Значение цвета остановки",
"position": "Положение остановки",
"addMiddle": "Добавить цвет посередине",
"delete": "Удалить выбранную остановку",
"hint": "Дважды щёлкните, чтобы добавить · Перетащите остановку, чтобы переместить · Дважды щёлкните по остановке, чтобы удалить"
},
"attributeControl": {
"angleOffset": "Смещение угла",
"value": "Значение",
"lower": "Минимум",
"upper": "Максимум",
"rangeLower": "Нижняя граница диапазона",
"rangeUpper": "Верхняя граница диапазона",
"curveInput": "Вход кривой →",
"direction": "Направление эмиссии"
},
"pivot": {
"title": "Опорная точка текстуры",
"zoomOut": "Уменьшить",
"zoomIn": "Увеличить",
"expand": "Открыть полноэкранный редактор опорной точки",
"interaction": "Щёлкните или перетащите, чтобы задать опорную точку · Перетаскивание правой кнопкой — панорамирование · Прокрутка — масштаб",
"previewAlt": "Предпросмотр опорной точки",
"noImage": "Изображение не выбрано",
"resetCenter": "По центру (50%, 50%)",
"coordinates": "Координаты опорной точки (%)",
"rotationTest": "Проверка вращения вокруг опорной точки",
"static": "Статично",
"spin": "Вращение",
"swing": "Колебание",
"rotationAlt": "Проверка вращения",
"topLeft": "Сверху слева",
"top": "Сверху",
"topRight": "Сверху справа",
"left": "Слева",
"center": "По центру",
"right": "Справа",
"bottomLeft": "Снизу слева",
"bottom": "Снизу",
"bottomRight": "Снизу справа"
},
"image": {
"chooseSequence": "Выбрать кадры последовательности",
"chooseLocal": "Выбрать локальное изображение",
"subfolder": "Подпапка",
"name": "Имя",
"restore": "Восстановить {name}",
"deleteResource": "Удалить ресурс изображения",
"imageMode": "Режим изображения",
"fixed": "Одно изображение",
"sequence": "Последовательность кадров",
"playbackMode": "Воспроизведение",
"onceHide": "Один раз, скрыть после последнего кадра",
"onceHold": "Один раз, удержать последний кадр",
"loopForward": "Цикл в прямом направлении",
"loopReverse": "Цикл в обратном направлении",
"playbackFps": "Частота воспроизведения, кадр/с",
"chooseSequenceMulti": "Выбрать кадры последовательности (несколько)",
"weight": "Вес, %",
"unlockWeight": "Разблокировать вес",
"lockWeight": "Зафиксировать текущий вес",
"pivot": "Опорная точка текстуры",
"collapsePivot": "Свернуть редактор опорной точки",
"expandPivot": "Развернуть редактор опорной точки",
"pivotModal": "Полноэкранная точная настройка опорной точки",
"pivotModalDesc": "Щёлкните или перетащите по текстуре, чтобы точно задать центр вращения и колебания частицы",
"pivotZoomHint": "Поддерживается увеличение от 100% до 400% для точного совмещения с кончиком или основанием:",
"confirmPivot": "Применить и сохранить опорную точку",
"noSequence": "Последовательность кадров не выбрана",
"firstFrame": "Кадр 1",
"firstImage": "первое изображение",
"lastImage": "последнее изображение",
"pivotOn": "Включено: X {x}% | Y {y}%",
"pivotOff": "Отключено, используется центр изображения (50%, 50%)",
"pivotCustom": "Пользовательская опорная точка: X {x}% | Y {y}%",
"frameCountOne": "1 кадр · {name}",
"frameCountMany": "Кадров: {count} · {first} → {last}",
"sequenceSelected": "Выбрано кадров: {count}; воспроизведение от {first} до {last}"
},
"timeline": {
"play": "Воспроизвести (D)",
"pause": "Пауза (D)",
"toStart": "Перейти к первому кадру (S)",
"previous": "Предыдущий кадр",
"next": "Следующий кадр",
"toEnd": "Перейти к последнему кадру",
"continuousLoop": "Непрерывное циклическое воспроизведение",
"abLoop": "Независимый цикл диапазона A/B",
"abLoopShort": "Цикл A/B",
"abRange": "Диапазон цикла A/B",
"playbackStart": "Пользовательский начальный кадр воспроизведения",
"playbackEnd": "Пользовательский конечный кадр воспроизведения",
"startFrame": "Начальный кадр воспроизведения",
"endFrame": "Конечный кадр воспроизведения",
"frame": "Кадр",
"emission": "Испускание",
"particleLife": "Активные частицы",
"spineAnimation": "Анимация Spine",
"ownerAnimation": "Связанная анимация",
"setOwnerAnimation": "Выбрать анимацию, к которой относится система частиц",
"chooseOwnerAnimation": "Выбрать связанную анимацию",
"animationName": "Имя анимации",
"renameAnimation": "Переименовать текущую анимацию",
"rename": "Переименовать",
"newAnimation": "+ Новая",
"keepOneAnimation": "Должна остаться хотя бы одна анимация",
"spinePreview": "Анимация предпросмотра Spine",
"noSpineAnimation": "Нет доступных анимаций Spine",
"none": "Нет",
"systemName": "Система {index}",
"dragLoopDuration": "Перетащите, чтобы изменить длительность цикла",
"dragEmissionDuration": "Перетащите, чтобы изменить длительность испускания",
"dragSpineStart": "Перетащите, чтобы изменить время начала анимации",
"noAnimationData": "Нет данных анимации для отображения",
"animationNameEmpty": "Имя анимации не может быть пустым",
"animationNameDuplicate": "Анимация с таким именем уже существует",
"animationRenameFailed": "Не удалось переименовать анимацию",
"zoomIn": "Увеличить",
"zoomOut": "Уменьшить",
"zoomFit": "Вписать",
"frameStatus": "Кадр {current} / {total}"
},
"emission": {
"title": "Эмиссия",
"reset": "Сбросить параметры эмиссии",
"stream": "Поток",
"burst": "Пакетное испускание",
"normalStream": "Обычный поток",
"loopStream": "Циклический поток",
"rate": "Интенсивность эмиссии",
"duration": "Длительность эмиссии",
"loopDuration": "Длительность эмиссии (кадр.)",
"generateStart": "Создать начальную анимацию цикла",
"generateEnd": "Создать конечную анимацию цикла",
"customDuration": "Пользовательская длительность",
"auto": "Авто, {frames} кадр.",
"startLoopDuration": "Длительность начального участка цикла",
"endLoopDuration": "Длительность конечного участка цикла",
"loopWarning": "В режиме циклического потока следование за костью и путём недоступно; при входе и выходе настройки следования сбрасываются.",
"burstCount": "Количество в пакете",
"delay": "Задержка",
"shapeTitle": "Форма эмиттера",
"shapeReset": "Сбросить параметры формы эмиттера",
"shape": "Форма",
"point": "Точка",
"circle": "Окружность",
"rect": "Прямоугольник",
"cone": "Конус",
"path": "Путь",
"innerDiameter": "Внутренний диаметр",
"outerDiameter": "Внешний диаметр",
"innerRadius": "Внутренний радиус",
"outerRadius": "Внешний радиус",
"coneDirection": "Направление конуса",
"coneAngle": "Угол раскрытия конуса",
"innerWidth": "Внутренняя ширина",
"innerHeight": "Внутренняя высота",
"outerWidth": "Внешняя ширина",
"outerHeight": "Внешняя высота",
"selectPath": "Путь генерации",
"noPath": "Без пути (испускание из точки)",
"birthDistribution": "Распределение рождения",
"evenDistribution": "Равномерное фиксированное распределение",
"randomDistribution": "Случайное распределение",
"emissionAngle": "Угол эмиссии",
"radial": "Радиальное (из центра наружу)",
"pathNormal": "Нормаль к пути",
"pathTangent": "По касательной к пути",
"fixedAngle": "Фиксированный угол",
"baseAngle": "Базовый угол",
"randomRange": "Случайный диапазон",
"showShape": "Показать форму"
},
"attributes": {
"title": "Свойства частиц",
"reset": "Сбросить параметры частиц",
"initialParams": "Начальные параметры частиц",
"initialLife": "Начальное время жизни",
"randomSample": "Случайная выборка →",
"initialSpeed": "Начальная скорость",
"initialScale": "Начальный масштаб",
"uniform": "Равномерно",
"separateXY": "Раздельно XY",
"scaleX": "Масштаб X",
"scaleY": "Масштаб Y",
"initialRotation": "Начальный поворот",
"lifecycleTitle": "Параметры на протяжении времени жизни",
"speedOverLife": "Скорость на протяжении времени жизни",
"speedMultiplier": "Множитель скорости",
"lifeTo": "Время жизни →",
"scaleOverLife": "Масштаб на протяжении времени жизни",
"scaleMultiplier": "Множитель масштаба",
"multiplierX": "Множитель X",
"multiplierY": "Множитель Y",
"rotationOverLife": "Вращение на протяжении времени жизни",
"rotationSpeed": "Скорость вращения"
},
"appearance": {
"title": "Внешний вид и ресурсы",
"reset": "Сбросить настройки внешнего вида и ресурсов",
"opacity": "Непрозрачность",
"curveMode": "Режим кривой",
"transparent": "0 (прозрачный)",
"opaque": "1 (непрозрачный)",
"renderLayer": "Слой отрисовки (слот Spine)",
"top": "Самый верхний",
"spineSlot": "Слот Spine",
"selectSpine": "Выберите Spine",
"noSpine": "Нет доступных ресурсов Spine",
"noSlot": "Слот не выбран",
"reselect": "Выбрать заново",
"selectSlot": "Выбрать слот",
"searchSlots": "Поиск слотов или вложений…",
"searchSlotsAria": "Поиск слотов",
"emptySlot": "Пустой слот",
"noMatchingSlots": "Подходящие слоты не найдены",
"above": "Над изображением слота",
"below": "Под изображением слота",
"followAttachment": "Следовать видимости вложения",
"previewOnly": "Изменение слоя влияет только на предпросмотр в редакторе и не экспортируется.",
"imageResources": "Ресурсы изображений",
"addImage": "Добавить ресурс изображения",
"scale": "Масштаб",
"color": "Цвет",
"fixedColor": "Фиксированный цвет",
"randomColor": "Случайный цвет",
"lifetime": "На протяжении времени жизни",
"normal": "Обычный",
"add": "Сложение",
"multiply": "Умножение",
"screen": "Экранный",
"fixedColorValue": "Значение фиксированного цвета",
"randomColorHint": "Каждая частица выбирает цвет из градиента при рождении и сохраняет его до завершения времени жизни",
"independentAlpha": "Независимая непрозрачность",
"off": "Выключено"
},
"renderLayer": {
"slotLabelAbove": "{spine} / {slot} · над изображением",
"slotLabelBelow": "{spine} / {slot} · под изображением",
"resolvedAbove": "Отрисовка над изображением {slot} и под следующим слотом",
"resolvedBetween": "Отрисовка между {previous} и {slot}",
"warningNoSpine": "Загруженный Spine не найден. Частицы временно отрисовываются сверху.",
"warningNoSelection": "Spine не выбран. Частицы временно отрисовываются сверху.",
"warningMissingSpine": "Целевой Spine больше не существует. Частицы временно отрисовываются сверху.",
"warningNotReady": "Целевой Spine не готов. Частицы временно отрисовываются сверху.",
"warningMissingSlot": "Целевой слот не существует; возможно, ресурсы были заменены. Частицы временно отрисовываются сверху.",
"warningFirstSlot": "Это первый слот, поэтому отрисовка под ним невозможна. Частицы временно отрисовываются сверху."
},
"export": {
"title": "Экспорт ресурсов",
"reset": "Сбросить параметры экспорта",
"imagesPath": "Путь к изображениям (Spine Images Path)",
"spineVersion": "Версия Spine",
"keyframeCurve": "Интерполяция ключевых кадров",
"linear": "Линейная (Linear)",
"smoothBezier": "Сглаженная Безье (Smooth Bézier)",
"bezierHelp": "Сглаженная Безье аппроксимирует непрерывное движение в пределах допуска; рождение, смерть, смена вложения и резкие переходы по-прежнему используют ступенчатые ключи.",
"spine38Help": "Spine 3.8 не поддерживает массивы кривых Безье для отдельных каналов. При экспорте они преобразуются в кусочно-линейные ключи с упрощением по допуску.",
"fps": "Частота экспорта, кадр/с",
"omitFps": "Не записывать fps",
"fpsHelp": "При изменении FPS фактическая длительность анимации сохраняется; «Не записывать fps» лишь удаляет метаданные FPS в Spine.",
"integerFrames": "Выравнивание по целым кадрам",
"bonePool": "Пул объектов костей",
"excludeEmpty": "Исключать пустые анимации",
"baking": "Пересчёт и запекание анимации",
"exportJsonTitle": "Экспортировать JSON Spine {version}",
"preparing": "Подготовка экспорта…",
"exportJson": "Экспортировать Spine JSON",
"exportImagesTitle": "Скачать изображения текущих систем частиц в ZIP-архиве",
"organizingImages": "Подготовка изображений…",
"exportImages": "Экспортировать архив images",
"generatingProject": "Создание проекта…",
"exportSpine": "Экспортировать пакет .spine",
"authorize": "Авторизовать текущий сайт",
"authorizeTitle": "Авторизовать текущий сайт в локальном коннекторе",
"refreshConnector": "Повторно проверить коннектор",
"refresh": "Обновить",
"recalculating": "Пересчёт анимации частиц…",
"exported": "Экспортирован Spine {version}: систем частиц — {systems}, анимаций — {animations}, костей — {bones}{warning}",
"resourceWarning": "; предупреждений о ресурсах — {count} (экспорт выполнен без отсутствующих изображений)",
"timeout": "Истекло время запекания. Убедитесь, что страница всё ещё работает, и повторите попытку.",
"preparingProject": "Подготовка изображений и вызов локального Spine…",
"projectExported": "Создан {fileName}: проект .spine с изображениями ({images}), Spine {version}",
"collectingImages": "Сбор изображений, используемых текущими системами частиц…",
"imagesExported": "Создан {fileName}: изображений — {images}, папка {folder}/",
"connectorChecking": "Проверка локального коннектора Spine…",
"connectorOffline": "Локальный коннектор Spine не запущен",
"spineNotFound": "Коннектор запущен, но Spine не найден",
"notAuthorized": "Коннектор запущен, но текущий сайт не авторизован",
"connectorReady": "Коннектор доступен · Spine готов",
"connectorBusy": "Пересчёт и создание проекта Spine",
"connectorGenerate": "Создать проект Spine {version} с помощью локального Spine",
"unknown": "Неизвестно",
"checking": "Проверка",
"offline": "Не запущен",
"notFound": "Spine не найден",
"unauthorized": "Нет авторизации",
"projectTransferTitle": "Экспорт пакета Spine",
"projectTransferDetail": "Пересчёт анимации частиц…",
"projectTransferDownload": "Загрузка проекта Spine началась",
"generatingJson": "Создание JSON Spine…",
"preparingProjectFiles": "Подготовка изображений проекта…",
"uploading": "Передача данных в коннектор Spine…",
"spineProcessing": "Spine преобразует проект. Подождите…",
"downloadingProject": "Загрузка созданного проекта Spine…",
"handingToBrowser": "Передача загрузки браузеру…"
},
"transfer": {
"completed": "Завершено",
"failed": "Ошибка операции"
},
"scene": {
"title": "Объекты сцены",
"addParticle": "Добавить систему частиц",
"addParticleShort": "+Частицы",
"addCollider": "Добавить коллайдер",
"addColliderShort": "+Коллайдер",
"addPath": "Добавить путь",
"addPathShort": "+Путь",
"addSpine": "Добавить Spine",
"copyTitle": "Дублировать выбранный объект сцены",
"showParticle": "Показать систему частиц",
"hideParticle": "Скрыть систему частиц",
"showCollider": "Показать коллайдер",
"hideCollider": "Скрыть коллайдер",
"showPath": "Показать путь",
"hidePath": "Скрыть путь",
"showSpine": "Показать Spine",
"hideSpine": "Скрыть Spine",
"particle": "Частицы",
"subEmitter": "Дочерний эмиттер",
"collision": "Столкновение",
"path": "Путь",
"deleteParticle": "Удалить систему частиц",
"deleteCollider": "Удалить коллайдер",
"deletePath": "Удалить путь",
"deleteSpine": "Удалить Spine",
"empty": "На сцене нет объектов",
"name": "Имя",
"positionX": "Позиция X",
"positionY": "Позиция Y",
"offsetX": "Смещение X",
"offsetY": "Смещение Y",
"rotation": "Поворот",
"scaleX": "Масштаб X",
"scaleY": "Масштаб Y",
"warmupFrames": "Кадры предварительного прогрева",
"seed": "Случайное зерно",
"seedTitle": "Управляет всеми случайными свойствами системы частиц, выбором ресурсов и случайной выборкой модификаторов",
"randomizeSeed": "Создать новое глобальное случайное зерно",
"seedHint": "Управляет начальными случайными параметрами, выбором ресурсов и выборкой модификаторов; одинаковое зерно воспроизводит одинаковый результат",
"colliderTitle": "Свойства коллайдера",
"colliderName": "Имя коллайдера",
"type": "Тип",
"circle": "Окружность",
"ellipse": "Эллипс",
"rect": "Прямоугольник",
"polygon": "Многоугольник",
"custom": "Пользовательский",
"enabled": "Включён",
"xPosition": "Позиция X",
"yPosition": "Позиция Y",
"scaleXShort": "Масштаб X",
"scaleYShort": "Масштаб Y",
"radius": "Радиус",
"radiusX": "Радиус X",
"radiusY": "Радиус Y",
"width": "Ширина",
"height": "Высота",
"sides": "Количество сторон",
"collisionResponse": "Реакция на столкновение",
"physics": "Физика (отскок / трение)",
"pause": "Остановить на месте",
"destroy": "Уничтожить сразу",
"elasticity": "Упругость (0–1)",
"friction": "Трение (0–1)",
"followPath": "Движение по пути",
"targetPath": "Целевой путь",
"notSelected": "(Не выбрано)",
"moveDuration": "Длительность перемещения (с)",
"followDirection": "Ориентация по пути",
"moveProgressCurve": "Кривая прогресса перемещения",
"moveProgressHelp": "X: прошедшее время / длительность · Y: прогресс пути (0 = начало, 1 = конец)",
"pathTitle": "Свойства пути",
"pathName": "Имя пути",
"closedPath": "Замкнутый путь",
"pathColor": "Цвет пути",
"pathHelp": "Управление:",
"pathHelpItems": [
"Дважды щёлкните по пустому месту или кривой, чтобы добавить опорную точку",
"Дважды щёлкните по опорной точке, чтобы удалить её",
"Дважды щёлкните, задержите второй щелчок и перетащите, чтобы создать управляющие маркеры",
"Перетаскивайте опорные точки для перемещения, а маркеры — для изменения кривой",
"Shift + перетаскивание маркера: симметричные маркеры",
"Alt + перетаскивание маркера: независимые маркеры",
"Ctrl + щелчок / рамка: добавить узлы",
"Alt + щелчок / рамка: убрать узлы",
"Alt + щелчок по пустому месту: снять выделение",
"Несколько выбранных опорных точек можно перемещать вместе"
],
"applyPresetShape": "Применить готовую форму",
"choosePreset": "Выбрать шаблон…",
"square": "Квадрат",
"star": "Звезда",
"applyPreset": "Применить шаблон",
"clearAnchors": "Очистить опорные точки",
"panelHint": "Создавайте объекты сцены кнопками на панели сверху"
},
"modifiers": {
"title": "Модификаторы",
"reset": "Сбросить модификаторы",
"damping": "Затухание",
"enableNoise": "Включить шум движения",
"strength": "Сила",
"noiseRange": "Амплитуда отклонения",
"noiseSpeed": "Скорость изменения",
"noiseHint": "Сила задаёт степень влияния · Амплитуда ограничивает максимальное отклонение · Скорость изменения задаёт частоту вариаций",
"enableGravity": "Включить гравитацию",
"gravityStrength": "Сила гравитации",
"strengthMin": "Мин. сила",
"strengthMax": "Макс. сила",
"direction": "Направление",
"gravityOverLife": "Гравитация на протяжении времени жизни",
"windOverLife": "Ветер на протяжении времени жизни",
"axisStrength": "Ось Y: сила 0–1",
"directionHint": "0° — вправо · -90° — вниз · Отрицательная сила меняет направление",
"enableWind": "Включить ветер",
"windStrength": "Сила ветра",
"enableForceField": "Включить силовое поле",
"centerX": "Центр X",
"centerY": "Центр Y",
"forceStrength": "Сила поля",
"forceRadius": "Радиус поля",
"falloffMode": "Затухание",
"constant": "Постоянное (без изменения в радиусе)",
"linearFalloff": "Линейное (ноль на границе)",
"inverseFalloff": "Обратно пропорциональное расстоянию (максимум в центре)",
"forceHint": "Положительное значение притягивает · Отрицательное отталкивает · Круг поля можно перетаскивать на холсте",
"showShape": "Показать форму",
"enableVortex": "Включить вихрь",
"vortexHint": "Положительное значение — против часовой стрелки · Отрицательное — по часовой",
"enableAttraction": "Включить притяжение",
"attractionX": "Точка притяжения X",
"attractionY": "Точка притяжения Y",
"attractionRadius": "Радиус притяжения",
"attractionDuration": "Длительность притяжения",
"delay": "Задержка",
"delayMode": "Режим задержки",
"globalTime": "Общее время",
"particleLife": "Время жизни частицы",
"attractionPath": "Траектория притяжения",
"straight": "Прямая",
"attractionHint": "Притяжение начинается после задержки · Частица уничтожается при входе в красный радиус · Круг притяжения можно перетаскивать на холсте",
"enableTrail": "Включить шлейф",
"trailImages": "Отдельные изображения шлейфа",
"addTrailImage": "Добавить ресурс изображения шлейфа",
"trailRotation": "Поворот",
"trailBones": "Количество костей шлейфа",
"trailRatio": "Доля шлейфа (%)",
"trailLength": "Длина шлейфа",
"randomRange": "Случайный диапазон",
"lengthRatio": "Доля длины (%)",
"lengthMin": "Мин. длина (%)",
"lengthMax": "Макс. длина (%)",
"trailWidth": "Ширина шлейфа",
"widthRatio": "Доля ширины (%)",
"widthMin": "Мин. ширина (%)",
"widthMax": "Макс. ширина (%)",
"widthScale": "Масштаб ширины",
"followParticle": "Следовать за частицей",
"lifeLengthCurve": "Длина на протяжении времени жизни",
"shapeCurve": "Кривая формы (ширина от начала к концу)",
"colorMode": "Режим цвета",
"blendMode": "Режим смешивания",
"fixedColor": "Фиксированный цвет",
"alphaMode": "Режим непрозрачности",
"opacity": "Непрозрачность",
"gridRows": "Количество строк сетки",
"gridCols": "Количество столбцов сетки",
"trailHint": "Для каждой частицы создаётся группа одноуровневых костей шлейфа согласно доле ресурса; случайные длина и ширина фиксируются при рождении и воспроизводятся с тем же зерном",
"enableFollow": "Включить следование эмиттера",
"followMode": "Режим следования",
"noFollow": "Нет",
"followPath": "Следовать по пути",
"selectedBone": "Выбранная кость",
"emitterAngleMode": "Режим угла эмиттера",
"fixedAngle": "Фиксированный угол",
"followMoveDirection": "Следовать направлению движения",
"moveProgressCurve": "Кривая прогресса перемещения (0→1)",
"moveDuration": "Длительность перемещения (с)",
"followSpace": "Пространство следования",
"localSpace": "Локальное пространство (перемещение эмиттера)",
"worldSpace": "Мировое пространство (перемещение точки рождения)",
"moveDirection": "Направление движения",
"forward": "Прямое (начало → конец)",
"reverse": "Обратное (конец → начало)",
"followOffset": "Начальное смещение (0–1)",
"followSpaceHint": "В локальном пространстве перемещается весь эмиттер. В мировом пространстве перемещается только точка рождения; уже созданные частицы остаются в мировых координатах.",
"followTarget": "Цель следования: ",
"noValidBone": "Допустимая кость не привязана. Сначала выберите кость в иерархии Spine.",
"rebind": "Привязать заново",
"bind": "Привязать",
"selectedBoneLabel": "Текущая кость: ",
"boneLocalSpace": "Локальное пространство (следовать за костью)",
"boneWorldSpace": "Мировое пространство (сохранять позицию частицы)",
"offsetX": "Смещение позиции X",
"offsetY": "Смещение позиции Y",
"rotationOffset": "Смещение поворота",
"scaleOffsetX": "Смещение масштаба X",
"scaleOffsetY": "Смещение масштаба Y",
"boneFollowHint": "Эмиттер следует только за позицией выбранной кости Spine и не наследует поворот или масштаб Spine; для преобразования частиц используются параметры системы частиц и смещения выше.",
"enableCollision": "Включить столкновения",
"collisionObjects": "Участвующие объекты столкновений",
"colliderDisabled": "{name} (коллайдер отключён)",
"clearCollider": "Удалить коллайдер {name} из списка",
"addCollider": "Добавить коллайдер сцены",
"noAvailableColliders": "Нет доступных коллайдеров",
"noCollidersSelected": "Коллайдеры не выбраны; столкновения текущих частиц отключены",
"available": "Доступен",
"disabled": "Отключён",
"collisionHint": "В столкновениях текущей системы участвуют только добавленные и включённые коллайдеры сцены",
"enableSubEmitter": "Включить дочерние эмиттеры",
"triggerTiming": "Событие запуска",
"birth": "Рождение",
"death": "Смерть",
"collision": "Столкновение",
"chooseTarget": "Выбрать целевую систему частиц",
"noTarget": "Нет (система частиц)",
"deleteSubEmitter": "Удалить этот дочерний эмиттер",
"probability": "Вероятность запуска",
"collisionLimit": "Лимит запусков при столкновениях",
"inherit": "Наследование",
"colorInheritMode": "Режим наследования цвета",
"add": "Сложение",
"replace": "Замена",
"addSubEmitter": "+ Добавить дочерний эмиттер",
"inheritNone": "Нет (по умолчанию)",
"inheritAll": "Все свойства",
"inheritColor": "Цвет",
"inheritScale": "Размер",
"inheritRotation": "Поворот",
"inheritLife": "Время жизни"
},
"spine": {
"title": "Свойства Spine",
"name": "Имя Spine",
"xPosition": "Позиция X",
"yPosition": "Позиция Y",
"rotation": "Поворот",
"scaleX": "Масштаб X",
"scaleY": "Масштаб Y",
"startTime": "Время начала",
"resources": "Ресурсы Spine",
"chooseFolder": "Выбрать папку и загрузить",
"folderHint": "Однократно считывает JSON / SKEL, Atlas и все текстуры из папки; отдельные ресурсы всё равно можно заменить ниже.",
"choose": "Выбрать",
"chooseMultiple": "Выбрать несколько",
"loading": "Загрузка…",
"load": "↧ Загрузить",
"clear": "Очистить",
"supportNote": "Поддержка JSON Spine 3.8 / 4.0 / 4.1 / 4.2 / 4.3 · Среда выполнения нужной версии загружается по требованию · Полностью локально",
"currentResource": "Текущий ресурс {version}",
"animations": "Анимации Spine",
"noAnimations": "Нет доступных анимаций",
"timelineAnimation": "Анимация на временной шкале",
"no": "Нет",
"hierarchy": "Иерархия",
"clearBoneTitle": "Нажмите, чтобы снять выбор кости",
"noBoneTitle": "Кость не выбрана",
"clearBone": "Снять выбор кости: {name}",
"currentBone": "Текущая кость: ",
"clearSlotTitle": "Нажмите, чтобы снять выбор слота",
"noSlotTitle": "Слот не выбран",
"clearSlot": "Снять выбор слота: {name}",
"currentSlot": "Текущий слот: ",
"notSelected": "Не выбрано",
"expandAll": "Развернуть всё",
"collapseAll": "Свернуть всё",
"bones": "Кости",
"slots": "Слоты",
"notLoaded": "Spine не загружен",
"searchBones": "Поиск костей",
"searchBonesPlaceholder": "Поиск по именам костей…",
"clearSearch": "Очистить поиск",
"clearBoneSearch": "Очистить поиск костей",
"noMatchingBones": "Подходящие кости не найдены",
"expandChildren": "Развернуть дочерние кости",
"collapseChildren": "Свернуть дочерние кости",
"notLoadedSlots": "Слоты Spine не загружены",
"searchSlots": "Поиск слотов",
"searchSlotsPlaceholder": "Поиск слотов или вложений…",
"clearSlotSearch": "Очистить поиск слотов",
"noMatchingSlots": "Подходящие слоты не найдены",
"slotTitle": "{name} (кость: {bone}, вложение: {attachment})",
"empty": "Пусто",
"textureSummary": "Текстур: {count} · {names}",
"textureImages": "изображения текстур",
"missingFolderAssets": "В выбранной папке отсутствует: {missing}",
"chooseAssets": "Последовательно выберите данные Spine, Atlas и все изображения текстур"
},
"help": {
"title": "Справка",
"subtitle": "Краткое руководство: от создания частиц до сохранения и экспорта",
"close": "Закрыть справку",
"closeShort": "Закрыть (Esc)",
"quickStart": "Быстрый старт",
"stepCreate": "Создание объектов: на панели «Объекты сцены» используйте +Частицы / +Коллайдер / +Путь / +Spine.",
"stepEdit": "Редактирование частиц: выберите систему частиц и последовательно настройте «Эмиссия → Форма эмиттера → Свойства частиц → Внешний вид и ресурсы → Модификаторы».",
"stepPreview": "Просмотр результата: на временной шкале внизу можно воспроизводить, ставить паузу, перемещаться по кадрам или перетаскивать указатель; после изменения параметров анимация пересчитывается автоматически.",
"stepExport": "Сохранение и экспорт: «Сохранить конфигурацию» сохраняет проект; «Spine JSON / архив images / пакет .spine» создаёт итоговые файлы.",
"quickNote": "Кнопка «Сбросить» справа от заголовка каждого блока восстанавливает стандартные параметры. Системные настройки автоматически сохраняются в текущем браузере.",
"commonOps": "Основные действия",
"eye": "Видимость",
"eyeDesc": "Показывает или скрывает отдельный объект. Скрытые системы частиц не экспортируются.",
"copyDesc": "Полностью дублирует выбранный объект для сравнения параметров.",
"backgroundDesc": "Загружает опорное изображение и позволяет настроить его положение и непрозрачность только для предпросмотра на холсте.",
"settingsDesc": "Управление расположением интерфейса, вспомогательными элементами, делениями и другими настройками; значения автоматически сохраняются в браузере.",
"undoDesc": "Ctrl+Z отменяет одно действие. Максимальное число шагов задаётся в системных настройках.",
"spineBoneDesc": "Найдите и выберите кость в иерархии для следования эмиттера.",
"shortcuts": "Горячие клавиши",
"undoShortcut": "Отменить действие",
"saveShortcut": "Сохранить конфигурацию",
"panShortcut": "Перемещение холста",
"translateShortcut": "Инструмент перемещения",
"rotateShortcut": "Инструмент поворота",
"scaleShortcut": "Инструмент масштабирования",
"playShortcut": "Воспроизведение / пауза",
"startShortcut": "Перейти к первому кадру",
"shortcutNote": "Перед использованием Q / W / E / R щёлкните по холсту. При вводе текста в полях одиночные горячие клавиши не срабатывают.",
"modules": "Подробное описание модулей",
"configTitle": "Управление конфигурацией",
"saveConfigDesc": "Сохраняет все объекты сцены и параметры в JSON-файл проекта; также поддерживается Ctrl+S.",
"loadConfigDesc": "Загружает локальный файл конфигурации и полностью восстанавливает проект.",
"presetDesc": "Выберите шаблон в раскрывающемся списке для быстрого применения; нажмите на список ещё раз, чтобы обновить его.",
"configScope": "Область действия",
"configScopeDesc": "Конфигурация содержит объекты и параметры; интерфейс и системные настройки хранятся в браузере отдельно.",
"sceneTitle": "Объекты сцены",
"particleDesc": "Основной объект. Позволяет задать позицию, смещение, поворот, масштаб и случайное зерно; одинаковое зерно воспроизводит одинаковый результат.",
"colliderDesc": "Окружность, эллипс, прямоугольник, многоугольник или пользовательская форма; поддерживаются физический отскок, остановка, уничтожение и движение по пути.",
"pathDesc": "Путь Безье с опорными точками, управляющими маркерами, замыканием, цветом и готовыми формами.",
"spineDesc": "Загрузка данных Spine, Atlas и текстур; просмотр костей и слотов и их использование для следования эмиттера.",
"sceneCommonDesc": "Объекты можно независимо скрывать, показывать и дублировать; скрытые системы частиц не экспортируются.",
"emissionDesc": "Потоковая эмиссия, пакетное испускание, задержка и трёхчастный циклический поток с начальным, циклическим и конечным участками.",
"burstDesc": "Однократное испускание заданного числа частиц.",
"delayDesc": "Время ожидания до начала эмиссии; отображается у левого края полосы частиц.",
"loopNote": "Циклический поток не поддерживает следование за костью и путём; при переключении эти настройки сбрасываются.",
"shapeDesc": "Точка, окружность, прямоугольник, конус или путь в качестве области рождения. Для окружности и конуса используются внутренний и внешний радиусы, для прямоугольника — внутренние и внешние размеры.",
"angleDesc": "Фиксированный или случайный угол, радиальное направление, нормаль или касательная к пути.",
"initialDesc": "Время жизни, скорость, масштаб и поворот поддерживают фиксированный, случайный и криволинейный режимы. Поворот может следовать направлению эмиссии.",
"overLifeDesc": "Множитель скорости, масштаба и скорость вращения можно задавать кривыми на протяжении времени жизни.",
"alphaDesc": "Непрозрачность может быть фиксированной или задаваться кривой; режим кривой может следовать настройкам экспорта, быть линейным или Безье.",
"imageDesc": "Одно изображение или последовательность кадров, случайный выбор изображений по весу, опорные точки, цвет, режимы смешивания и независимая непрозрачность.",
"sequenceDesc": "Доступны режимы однократного скрытия, удержания последнего кадра, прямого и обратного цикла.",
"noiseDesc": "Добавляет шум траектории с управлением силой, амплитудой и скоростью.",
"gravityDesc": "Гравитация, ветер и кривые силы на протяжении времени жизни.",
"forceDesc": "Глобальное силовое поле, вихрь, притяжение и столкновения.",
"trailDesc": "Отдельные ресурсы шлейфа, число костей, длина, ширина, форма, цвет и кривые непрозрачности.",
"followDesc": "Эмиттер может следовать по пути или за костью Spine.",
"collisionDesc": "Выбор коллайдеров сцены и реакции частиц на столкновения.",
"exportDesc": "Настройка пути к изображениям, версии Spine, кривых ключевых кадров, FPS, целых кадров, пула костей и пустых анимаций.",
"exportButtonsDesc": "Экспорт Spine JSON, ZIP-архива images или создание проекта .spine через коннектор.",
"connectorTitle": "Справка по коннектору Spine",
"connectorIntro": "Коннектор передаёт созданные на веб-странице JSON и изображения в установленный и активированный локальный Spine и преобразует их в редактируемый проект .spine.",
"prerequisite": "Предварительные требования",
"prerequisiteDesc": "Spine должен быть установлен и активирован, а настольная версия коннектора — запущена.",
"download": "Скачать",
"webSide": "Веб-версия",
"webSideDesc": "Когда появится сообщение «Коннектор доступен · Spine готов», нажмите «Экспортировать пакет .spine».",
"authorization": "Первая авторизация",
"authorizationDesc": "При первом подключении проверьте источник сайта и разрешите доступ один раз; коннектор сохранит локальный список разрешённых источников.",
"pathSetup": "Путь к приложению",
"pathSetupDesc": "Коннектор автоматически находит Spine. Если поиск не удался, укажите путь к приложению вручную.",
"downloadResult": "Результат загрузки",
"downloadResultDesc": "ZIP-архив содержит проект .spine и папку с изображениями.",
"version": "Версия",
"versionDesc": "Коннектор автоматически сопоставляет версию JSON с Spine 3.8–4.3.",
"security": "Безопасность",
"securityDesc": "Коннектор прослушивает только локальный адрес, хранит авторизацию и удаляет временные файлы после преобразования.",
"differenceTitle": "Чем конфигурация отличается от экспорта?",
"differenceDesc": "«Сохранить конфигурацию» сохраняет все объекты и параметры для дальнейшего редактирования. «Экспорт Spine JSON» включает только видимые системы частиц и запекает столкновения, следование, шлейфы и дочерние эмиттеры в данные отдельных анимаций."
},
"errors": {
"confirmLoopFollowEnter": "При включении циклического потока следование частиц будет отключено, его настройки сброшены, а кадры прогрева перестанут действовать. Продолжить?",
"confirmLoopFollowExit": "При выходе из циклического потока следование частиц будет отключено и его настройки сброшены. Продолжить?",
"invalidJson": "Файл конфигурации не является корректным JSON",
"invalidConfigFormat": "Это не файл конфигурации редактора SpineParticle",
"unsupportedConfigVersion": "Неподдерживаемая версия конфигурации: {version}",
"missingScene": "В файле конфигурации отсутствуют полные данные сцены",
"missingEmbeddedSpine": "Конфигурация не содержит встроенных исходных ресурсов Spine для повторного использования",
"chooseJsonConfig": "Выберите файл конфигурации .json",
"settingsInvalidJson": "Кэш системных настроек не является корректным JSON",
"settingsFormat": "Это не кэш системных настроек SpineParticle",
"settingsVersion": "Неподдерживаемая версия системных настроек: {version}",
"settingsMissing": "В кэше отсутствует раздел настроек settings",
"noExportableImages": "У видимых систем частиц нет изображений для экспорта",
"invalidZipPath": "Недопустимый путь в ZIP-файле",
"spineFileType": "Данные Spine должны иметь расширение .json или .skel",
"atlasFileType": "Файлы атласа должны иметь расширение .atlas",
"chooseTexture": "Выберите хотя бы одно изображение текстуры",
"binaryParseFailed": "Не удалось разобрать двоичные данные Spine (4.3: {v43}; старая версия: {v42})",
"invalidSpineJson": "Недопустимый формат Spine JSON",
"unsupportedSpineJsonVersion": "Неподдерживаемая версия Spine JSON. Поддерживаются версии: {versions}",
"unsupportedSpineDataVersion": "Неподдерживаемая версия данных Spine. Поддерживаются версии: {versions}",
"embeddedReadFailed": "Не удалось прочитать встроенный файл Spine: {name}",
"missingImageWarning": "Изображение «{file}» отсутствует или имеет нечитаемые размеры. Путь сохранён.",
"missingTrailImageWarning": "Изображение шлейфа «{file}» отсутствует. Путь сохранён.",
"emptyCacheWarning": "Для «{name}» нет кэша запечённых кадров.",
"readExportImageFailed": "Не удалось прочитать изображение для экспорта: {name}",
"connectorOffline": "Локальный коннектор Spine не обнаружен. Сначала запустите коннектор.",
"connectorHttpError": "Коннектор Spine вернул ошибку HTTP {status}",
"invalidTrailUV": "Сетка шлейфа «{name}» содержит недопустимые UV-координаты",
"missingTrailVertices": "В сетке шлейфа «{name}» отсутствуют данные вершин",
"trailIndexOutOfRange": "Индекс треугольника сетки шлейфа «{name}» выходит за допустимый диапазон",
"invalidTrailHull": "Недопустимое количество граничных вершин сетки шлейфа «{name}»",
"trailHullIndexOutOfRange": "Индекс граничного ребра сетки шлейфа «{name}» выходит за допустимый диапазон",
"invalidInfluenceCount": "Сетка шлейфа «{name}» содержит недопустимое количество влияний костей",
"missingBoneReference": "Сетка шлейфа «{name}» ссылается на несуществующую кость",
"invalidWeight": "Сетка шлейфа «{name}» содержит недопустимые веса",
"weightSum": "Сумма весов вершин сетки шлейфа «{name}» не равна 1",
"vertexCountMismatch": "Количество вершин сетки шлейфа «{name}» не соответствует количеству UV-координат",
"invalidInherit": "Значение inherit «{inherit}» кости «{name}» несовместимо с форматом JSON Spine {version}",
"trailBoneParent": "Кость шлейфа «{name}» должна быть прямым дочерним элементом кости системы частиц, а не частью цепочки костей",
"trailSlotEmpty": "Взвешенный слот шлейфа «{name}» не может использовать пустое вложение. На этапах отсутствия или смерти установите масштаб соответствующих костей равным нулю.",
"spine38Version": "Версия экспорта Spine 3.8 должна быть указана как 3.8",
"spine38Inherit": "Кость «{name}» в Spine 3.8 должна использовать transform вместо inherit",
"spine38SlotColor": "Временные шкалы цвета слота Spine 3.8 должны использовать color / twoColor",
"spine38AttachmentName": "Скрытые кадры временной шкалы вложений Spine 3.8 должны явно записывать name: null",
"spine38RotationAngle": "Временные шкалы поворота Spine 3.8 должны использовать angle",
"spine38Curve": "Spine 3.8 не поддерживает формат массивов кривых Spine 4.x",
"unsupportedExportVersion": "Неподдерживаемая версия экспорта. Поддерживаются версии Spine: {versions}",
"exportVersionMismatch": "Несовпадение версии экспорта: задан Spine {expected}, JSON содержит Spine {actual}",
"exportMissingBones": "В результате экспорта отсутствуют кости",
"missingAtlasTexture": "Текстура, на которую ссылается Atlas, не выбрана: {name}"
}
}
@@ -6,12 +6,12 @@
</div>
<div class="group-body config-management-body" v-show="sectionOpen('config')">
<div class="config-toolbar">
<button :title="$t('config.saveTitle')" data-matomo-event="config.save" @click="saveConfig">{{ $t('config.save') }}</button>
<button :title="$t('config.loadTitle')" data-matomo-event="config.load-file" @click="configFileInput?.click()">{{ $t('config.load') }}</button>
<select v-model="selectedPreset" :aria-label="$t('config.presets')" :disabled="!presetOptions.length || presetLoading" @pointerdown="refreshPresets" @focus="refreshPresets" @change="loadSelectedPreset">
<option value="">{{ presetOptions.length ? $t('config.selectPreset') : $t('config.noPresets') }}</option>
<option v-for="preset in presetOptions" :key="preset.file" :value="preset.file">{{ presetDisplayName(preset) }}</option>
</select>
<button :title="$t('config.saveTitle')" data-matomo-event="config.save" @click="saveConfig">{{ $t('config.save') }}</button>
<button :title="$t('config.loadTitle')" data-matomo-event="config.load-file" @click="configFileInput?.click()">{{ $t('config.load') }}</button>
<input ref="configFileInput" hidden type="file" accept=".json,application/json" @change="onConfigFileChange" />
</div>
<div v-if="configMessage" class="config-message" :class="{ error: configError }">{{ configMessage }}</div>
@@ -113,18 +113,19 @@ function presetDisplayName(preset: PresetOption) {
<style scoped>
.config-management-body { padding-bottom: 2px; }
.group-download {
margin-left: auto; height: 24px; padding: 0 8px; border: 1px solid #485673; border-radius: 5px;
background: #202a3b; color: #d7e0f0; font-size: 10px; font-weight: 700; cursor: pointer;
max-width: 50%; min-height: 24px; margin-left: auto; padding: 3px 8px; border: 1px solid #485673; border-radius: 5px;
background: #202a3b; color: #d7e0f0; font-size: 10px; font-weight: 700; line-height: 1.2;
white-space: normal; cursor: pointer;
}
.group-download:hover { border-color: #7774ff; background: #303858; color: #fff; }
.config-toolbar { display: grid; grid-template-columns: auto auto minmax(0,1fr); gap: 6px; margin-bottom: 10px; }
.config-toolbar { display: grid; grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: 6px; margin-bottom: 10px; }
.config-toolbar button,.config-toolbar select {
min-width: 0; height: 30px; box-sizing: border-box; border: 1px solid #3b4864; border-radius: 6px;
min-width: 0; min-height: 30px; box-sizing: border-box; border: 1px solid #3b4864; border-radius: 6px;
background: #263149; color: #d6def0; font-size: 11px;
}
.config-toolbar button { padding: 0 9px; cursor: pointer; }
.config-toolbar button { height: auto; padding: 5px 8px; line-height: 1.25; overflow-wrap: anywhere; white-space: normal; cursor: pointer; }
.config-toolbar button:hover { border-color: #7169dc; background: #343d68; color: #fff; }
.config-toolbar select { padding: 0 7px; overflow: hidden; text-overflow: ellipsis; }
.config-toolbar select { grid-column: 1 / -1; height: auto; padding: 6px 7px; overflow: hidden; text-overflow: ellipsis; }
.config-toolbar select:disabled { color: #68738a; background: #1b2130; }
.config-message { margin: -4px 0 9px; color: #83b9a2; font-size: 10px; }
.config-message.error { color: #e8959e; }