diff --git a/assets/datas/geoip/ad.srs b/assets/datas/geoip/ad.srs index 0f93a09..6a91c3f 100644 Binary files a/assets/datas/geoip/ad.srs and b/assets/datas/geoip/ad.srs differ diff --git a/assets/datas/geoip/ae.srs b/assets/datas/geoip/ae.srs index 42e8167..5116917 100644 Binary files a/assets/datas/geoip/ae.srs and b/assets/datas/geoip/ae.srs differ diff --git a/assets/datas/geoip/af.srs b/assets/datas/geoip/af.srs index 4f1b356..7683122 100644 Binary files a/assets/datas/geoip/af.srs and b/assets/datas/geoip/af.srs differ diff --git a/assets/datas/geoip/ag.srs b/assets/datas/geoip/ag.srs index 1d1b3bb..775f395 100644 Binary files a/assets/datas/geoip/ag.srs and b/assets/datas/geoip/ag.srs differ diff --git a/assets/datas/geoip/ai.srs b/assets/datas/geoip/ai.srs index 1835a46..752eadf 100644 Binary files a/assets/datas/geoip/ai.srs and b/assets/datas/geoip/ai.srs differ diff --git a/assets/datas/geoip/al.srs b/assets/datas/geoip/al.srs index 0dc6a67..4d4a289 100644 Binary files a/assets/datas/geoip/al.srs and b/assets/datas/geoip/al.srs differ diff --git a/assets/datas/geoip/am.srs b/assets/datas/geoip/am.srs index f464e3e..a445bc6 100644 Binary files a/assets/datas/geoip/am.srs and b/assets/datas/geoip/am.srs differ diff --git a/assets/datas/geoip/amazon.srs b/assets/datas/geoip/amazon.srs index 0611650..a29afad 100644 Binary files a/assets/datas/geoip/amazon.srs and b/assets/datas/geoip/amazon.srs differ diff --git a/assets/datas/geoip/ao.srs b/assets/datas/geoip/ao.srs index 0dd4c24..59591da 100644 Binary files a/assets/datas/geoip/ao.srs and b/assets/datas/geoip/ao.srs differ diff --git a/assets/datas/geoip/aq.srs b/assets/datas/geoip/aq.srs index 5796838..47dcbcd 100644 Binary files a/assets/datas/geoip/aq.srs and b/assets/datas/geoip/aq.srs differ diff --git a/assets/datas/geoip/ar.srs b/assets/datas/geoip/ar.srs index 6ef0ba9..1043108 100644 Binary files a/assets/datas/geoip/ar.srs and b/assets/datas/geoip/ar.srs differ diff --git a/assets/datas/geoip/as.srs b/assets/datas/geoip/as.srs index b6d4b5b..870adc0 100644 Binary files a/assets/datas/geoip/as.srs and b/assets/datas/geoip/as.srs differ diff --git a/assets/datas/geoip/at.srs b/assets/datas/geoip/at.srs index a2a807b..d95e157 100644 Binary files a/assets/datas/geoip/at.srs and b/assets/datas/geoip/at.srs differ diff --git a/assets/datas/geoip/au.srs b/assets/datas/geoip/au.srs index ec13628..3e940f1 100644 Binary files a/assets/datas/geoip/au.srs and b/assets/datas/geoip/au.srs differ diff --git a/assets/datas/geoip/aw.srs b/assets/datas/geoip/aw.srs index 52fd23a..e582e97 100644 Binary files a/assets/datas/geoip/aw.srs and b/assets/datas/geoip/aw.srs differ diff --git a/assets/datas/geoip/ax.srs b/assets/datas/geoip/ax.srs index d3bc596..a2222c6 100644 Binary files a/assets/datas/geoip/ax.srs and b/assets/datas/geoip/ax.srs differ diff --git a/assets/datas/geoip/az.srs b/assets/datas/geoip/az.srs index 5e27445..10c13cf 100644 Binary files a/assets/datas/geoip/az.srs and b/assets/datas/geoip/az.srs differ diff --git a/assets/datas/geoip/ba.srs b/assets/datas/geoip/ba.srs index d838bc1..0b2913d 100644 Binary files a/assets/datas/geoip/ba.srs and b/assets/datas/geoip/ba.srs differ diff --git a/assets/datas/geoip/bb.srs b/assets/datas/geoip/bb.srs index 02220b3..e16e87d 100644 Binary files a/assets/datas/geoip/bb.srs and b/assets/datas/geoip/bb.srs differ diff --git a/assets/datas/geoip/bd.srs b/assets/datas/geoip/bd.srs index 4124371..48aed34 100644 Binary files a/assets/datas/geoip/bd.srs and b/assets/datas/geoip/bd.srs differ diff --git a/assets/datas/geoip/be.srs b/assets/datas/geoip/be.srs index 6f24526..992a120 100644 Binary files a/assets/datas/geoip/be.srs and b/assets/datas/geoip/be.srs differ diff --git a/assets/datas/geoip/bf.srs b/assets/datas/geoip/bf.srs index b028d46..655a0c0 100644 Binary files a/assets/datas/geoip/bf.srs and b/assets/datas/geoip/bf.srs differ diff --git a/assets/datas/geoip/bg.srs b/assets/datas/geoip/bg.srs index 3a5c586..bf67ef9 100644 Binary files a/assets/datas/geoip/bg.srs and b/assets/datas/geoip/bg.srs differ diff --git a/assets/datas/geoip/bh.srs b/assets/datas/geoip/bh.srs index 8d7a2fc..691b3d5 100644 Binary files a/assets/datas/geoip/bh.srs and b/assets/datas/geoip/bh.srs differ diff --git a/assets/datas/geoip/bi.srs b/assets/datas/geoip/bi.srs index 38b7c53..ef4304b 100644 Binary files a/assets/datas/geoip/bi.srs and b/assets/datas/geoip/bi.srs differ diff --git a/assets/datas/geoip/bj.srs b/assets/datas/geoip/bj.srs index b4305d8..14e0bc6 100644 Binary files a/assets/datas/geoip/bj.srs and b/assets/datas/geoip/bj.srs differ diff --git a/assets/datas/geoip/bl.srs b/assets/datas/geoip/bl.srs index 2f75ae5..cb67dd1 100644 Binary files a/assets/datas/geoip/bl.srs and b/assets/datas/geoip/bl.srs differ diff --git a/assets/datas/geoip/bm.srs b/assets/datas/geoip/bm.srs index 9f30080..bcbece6 100644 Binary files a/assets/datas/geoip/bm.srs and b/assets/datas/geoip/bm.srs differ diff --git a/assets/datas/geoip/bn.srs b/assets/datas/geoip/bn.srs index b8eb0cc..dab3565 100644 Binary files a/assets/datas/geoip/bn.srs and b/assets/datas/geoip/bn.srs differ diff --git a/assets/datas/geoip/bo.srs b/assets/datas/geoip/bo.srs index d20a3f4..6e307fe 100644 Binary files a/assets/datas/geoip/bo.srs and b/assets/datas/geoip/bo.srs differ diff --git a/assets/datas/geoip/bq.srs b/assets/datas/geoip/bq.srs index 8c0c825..c9418ed 100644 Binary files a/assets/datas/geoip/bq.srs and b/assets/datas/geoip/bq.srs differ diff --git a/assets/datas/geoip/br.srs b/assets/datas/geoip/br.srs index b2c6b34..b35f085 100644 Binary files a/assets/datas/geoip/br.srs and b/assets/datas/geoip/br.srs differ diff --git a/assets/datas/geoip/bs.srs b/assets/datas/geoip/bs.srs index 1a5ac9c..2f06ebc 100644 Binary files a/assets/datas/geoip/bs.srs and b/assets/datas/geoip/bs.srs differ diff --git a/assets/datas/geoip/bt.srs b/assets/datas/geoip/bt.srs index 5874136..e27f10a 100644 Binary files a/assets/datas/geoip/bt.srs and b/assets/datas/geoip/bt.srs differ diff --git a/assets/datas/geoip/bv.srs b/assets/datas/geoip/bv.srs index a3219da..8139969 100644 Binary files a/assets/datas/geoip/bv.srs and b/assets/datas/geoip/bv.srs differ diff --git a/assets/datas/geoip/bw.srs b/assets/datas/geoip/bw.srs index 7a1258a..927d4d6 100644 Binary files a/assets/datas/geoip/bw.srs and b/assets/datas/geoip/bw.srs differ diff --git a/assets/datas/geoip/by.srs b/assets/datas/geoip/by.srs index 05d452c..d610672 100644 Binary files a/assets/datas/geoip/by.srs and b/assets/datas/geoip/by.srs differ diff --git a/assets/datas/geoip/bz.srs b/assets/datas/geoip/bz.srs index 49d652b..1bc7b7c 100644 Binary files a/assets/datas/geoip/bz.srs and b/assets/datas/geoip/bz.srs differ diff --git a/assets/datas/geoip/ca.srs b/assets/datas/geoip/ca.srs index 317329a..f598ea9 100644 Binary files a/assets/datas/geoip/ca.srs and b/assets/datas/geoip/ca.srs differ diff --git a/assets/datas/geoip/cc.srs b/assets/datas/geoip/cc.srs index 26d3304..cfd2bd3 100644 Binary files a/assets/datas/geoip/cc.srs and b/assets/datas/geoip/cc.srs differ diff --git a/assets/datas/geoip/cd.srs b/assets/datas/geoip/cd.srs index d77b6c8..931544a 100644 Binary files a/assets/datas/geoip/cd.srs and b/assets/datas/geoip/cd.srs differ diff --git a/assets/datas/geoip/cf.srs b/assets/datas/geoip/cf.srs index 212466f..24836b7 100644 Binary files a/assets/datas/geoip/cf.srs and b/assets/datas/geoip/cf.srs differ diff --git a/assets/datas/geoip/cg.srs b/assets/datas/geoip/cg.srs index a7f3df6..b8c89a4 100644 Binary files a/assets/datas/geoip/cg.srs and b/assets/datas/geoip/cg.srs differ diff --git a/assets/datas/geoip/ch.srs b/assets/datas/geoip/ch.srs index 09aeed7..b513ef3 100644 Binary files a/assets/datas/geoip/ch.srs and b/assets/datas/geoip/ch.srs differ diff --git a/assets/datas/geoip/ci.srs b/assets/datas/geoip/ci.srs index 067da14..9b5e3cb 100644 Binary files a/assets/datas/geoip/ci.srs and b/assets/datas/geoip/ci.srs differ diff --git a/assets/datas/geoip/ck.srs b/assets/datas/geoip/ck.srs index 7006107..9b7b613 100644 Binary files a/assets/datas/geoip/ck.srs and b/assets/datas/geoip/ck.srs differ diff --git a/assets/datas/geoip/cl.srs b/assets/datas/geoip/cl.srs index 9d8eedd..2b9a8f2 100644 Binary files a/assets/datas/geoip/cl.srs and b/assets/datas/geoip/cl.srs differ diff --git a/assets/datas/geoip/cloudflare.srs b/assets/datas/geoip/cloudflare.srs index 7b0cd04..97f7b6f 100644 Binary files a/assets/datas/geoip/cloudflare.srs and b/assets/datas/geoip/cloudflare.srs differ diff --git a/assets/datas/geoip/cm.srs b/assets/datas/geoip/cm.srs index d03e71d..a2438a3 100644 Binary files a/assets/datas/geoip/cm.srs and b/assets/datas/geoip/cm.srs differ diff --git a/assets/datas/geoip/cn.srs b/assets/datas/geoip/cn.srs index 06f9f08..6563bce 100644 Binary files a/assets/datas/geoip/cn.srs and b/assets/datas/geoip/cn.srs differ diff --git a/assets/datas/geoip/co.srs b/assets/datas/geoip/co.srs index eba5519..29ca100 100644 Binary files a/assets/datas/geoip/co.srs and b/assets/datas/geoip/co.srs differ diff --git a/assets/datas/geoip/cr.srs b/assets/datas/geoip/cr.srs index 7f68fc3..f8db8d6 100644 Binary files a/assets/datas/geoip/cr.srs and b/assets/datas/geoip/cr.srs differ diff --git a/assets/datas/geoip/cu.srs b/assets/datas/geoip/cu.srs index f37b2e0..0ff306e 100644 Binary files a/assets/datas/geoip/cu.srs and b/assets/datas/geoip/cu.srs differ diff --git a/assets/datas/geoip/cv.srs b/assets/datas/geoip/cv.srs index 13aeb8b..01f13ea 100644 Binary files a/assets/datas/geoip/cv.srs and b/assets/datas/geoip/cv.srs differ diff --git a/assets/datas/geoip/cw.srs b/assets/datas/geoip/cw.srs index c2853df..d019ed1 100644 Binary files a/assets/datas/geoip/cw.srs and b/assets/datas/geoip/cw.srs differ diff --git a/assets/datas/geoip/cx.srs b/assets/datas/geoip/cx.srs index 57a4004..5d78d1b 100644 Binary files a/assets/datas/geoip/cx.srs and b/assets/datas/geoip/cx.srs differ diff --git a/assets/datas/geoip/cy.srs b/assets/datas/geoip/cy.srs index 238d3c8..ce99b0c 100644 Binary files a/assets/datas/geoip/cy.srs and b/assets/datas/geoip/cy.srs differ diff --git a/assets/datas/geoip/cz.srs b/assets/datas/geoip/cz.srs index 1db532c..f72fd62 100644 Binary files a/assets/datas/geoip/cz.srs and b/assets/datas/geoip/cz.srs differ diff --git a/assets/datas/geoip/de.srs b/assets/datas/geoip/de.srs index 22e9114..1f9be32 100644 Binary files a/assets/datas/geoip/de.srs and b/assets/datas/geoip/de.srs differ diff --git a/assets/datas/geoip/digitalocean.srs b/assets/datas/geoip/digitalocean.srs index 5baab7c..f0232a1 100644 Binary files a/assets/datas/geoip/digitalocean.srs and b/assets/datas/geoip/digitalocean.srs differ diff --git a/assets/datas/geoip/dj.srs b/assets/datas/geoip/dj.srs index f385b80..178f6ce 100644 Binary files a/assets/datas/geoip/dj.srs and b/assets/datas/geoip/dj.srs differ diff --git a/assets/datas/geoip/dk.srs b/assets/datas/geoip/dk.srs index 999baf6..db5b903 100644 Binary files a/assets/datas/geoip/dk.srs and b/assets/datas/geoip/dk.srs differ diff --git a/assets/datas/geoip/dm.srs b/assets/datas/geoip/dm.srs index 75fc02d..f0cbfb1 100644 Binary files a/assets/datas/geoip/dm.srs and b/assets/datas/geoip/dm.srs differ diff --git a/assets/datas/geoip/do.srs b/assets/datas/geoip/do.srs index a7a7251..5848764 100644 Binary files a/assets/datas/geoip/do.srs and b/assets/datas/geoip/do.srs differ diff --git a/assets/datas/geoip/dz.srs b/assets/datas/geoip/dz.srs index ff171da..1030c20 100644 Binary files a/assets/datas/geoip/dz.srs and b/assets/datas/geoip/dz.srs differ diff --git a/assets/datas/geoip/ec.srs b/assets/datas/geoip/ec.srs index d2dab0f..59fa5e6 100644 Binary files a/assets/datas/geoip/ec.srs and b/assets/datas/geoip/ec.srs differ diff --git a/assets/datas/geoip/ee.srs b/assets/datas/geoip/ee.srs index c86b3a8..e46a73d 100644 Binary files a/assets/datas/geoip/ee.srs and b/assets/datas/geoip/ee.srs differ diff --git a/assets/datas/geoip/eg.srs b/assets/datas/geoip/eg.srs index 3a529f4..06d24e2 100644 Binary files a/assets/datas/geoip/eg.srs and b/assets/datas/geoip/eg.srs differ diff --git a/assets/datas/geoip/eh.srs b/assets/datas/geoip/eh.srs index 461d830..2c4c5f9 100644 Binary files a/assets/datas/geoip/eh.srs and b/assets/datas/geoip/eh.srs differ diff --git a/assets/datas/geoip/er.srs b/assets/datas/geoip/er.srs index a9576bd..0512b74 100644 Binary files a/assets/datas/geoip/er.srs and b/assets/datas/geoip/er.srs differ diff --git a/assets/datas/geoip/es.srs b/assets/datas/geoip/es.srs index c003f67..f37a257 100644 Binary files a/assets/datas/geoip/es.srs and b/assets/datas/geoip/es.srs differ diff --git a/assets/datas/geoip/et.srs b/assets/datas/geoip/et.srs index ad92f19..27a33b1 100644 Binary files a/assets/datas/geoip/et.srs and b/assets/datas/geoip/et.srs differ diff --git a/assets/datas/geoip/facebook.srs b/assets/datas/geoip/facebook.srs index 84b03fd..396738a 100644 Binary files a/assets/datas/geoip/facebook.srs and b/assets/datas/geoip/facebook.srs differ diff --git a/assets/datas/geoip/fastly.srs b/assets/datas/geoip/fastly.srs index 86a4d1d..a180f2e 100644 Binary files a/assets/datas/geoip/fastly.srs and b/assets/datas/geoip/fastly.srs differ diff --git a/assets/datas/geoip/fi.srs b/assets/datas/geoip/fi.srs index ed04c24..960daf6 100644 Binary files a/assets/datas/geoip/fi.srs and b/assets/datas/geoip/fi.srs differ diff --git a/assets/datas/geoip/fj.srs b/assets/datas/geoip/fj.srs index 043e7d4..dba5d6a 100644 Binary files a/assets/datas/geoip/fj.srs and b/assets/datas/geoip/fj.srs differ diff --git a/assets/datas/geoip/fk.srs b/assets/datas/geoip/fk.srs index 85b75e8..1c6497d 100644 Binary files a/assets/datas/geoip/fk.srs and b/assets/datas/geoip/fk.srs differ diff --git a/assets/datas/geoip/fm.srs b/assets/datas/geoip/fm.srs index 1b196f9..9531481 100644 Binary files a/assets/datas/geoip/fm.srs and b/assets/datas/geoip/fm.srs differ diff --git a/assets/datas/geoip/fo.srs b/assets/datas/geoip/fo.srs index 963c51c..450de03 100644 Binary files a/assets/datas/geoip/fo.srs and b/assets/datas/geoip/fo.srs differ diff --git a/assets/datas/geoip/fr.srs b/assets/datas/geoip/fr.srs index 532e0de..8901e6b 100644 Binary files a/assets/datas/geoip/fr.srs and b/assets/datas/geoip/fr.srs differ diff --git a/assets/datas/geoip/ga.srs b/assets/datas/geoip/ga.srs index 048df0a..11dfc0c 100644 Binary files a/assets/datas/geoip/ga.srs and b/assets/datas/geoip/ga.srs differ diff --git a/assets/datas/geoip/gb.srs b/assets/datas/geoip/gb.srs index 4e1f77c..89d8d8f 100644 Binary files a/assets/datas/geoip/gb.srs and b/assets/datas/geoip/gb.srs differ diff --git a/assets/datas/geoip/gd.srs b/assets/datas/geoip/gd.srs index 4058a4f..73e2148 100644 Binary files a/assets/datas/geoip/gd.srs and b/assets/datas/geoip/gd.srs differ diff --git a/assets/datas/geoip/ge.srs b/assets/datas/geoip/ge.srs index 600e73e..2b180bd 100644 Binary files a/assets/datas/geoip/ge.srs and b/assets/datas/geoip/ge.srs differ diff --git a/assets/datas/geoip/gf.srs b/assets/datas/geoip/gf.srs index 1752f09..1e8c13b 100644 Binary files a/assets/datas/geoip/gf.srs and b/assets/datas/geoip/gf.srs differ diff --git a/assets/datas/geoip/gg.srs b/assets/datas/geoip/gg.srs index 3564a68..57dd34b 100644 Binary files a/assets/datas/geoip/gg.srs and b/assets/datas/geoip/gg.srs differ diff --git a/assets/datas/geoip/gh.srs b/assets/datas/geoip/gh.srs index b2daea2..5492ab1 100644 Binary files a/assets/datas/geoip/gh.srs and b/assets/datas/geoip/gh.srs differ diff --git a/assets/datas/geoip/gi.srs b/assets/datas/geoip/gi.srs index b2d4c44..136d961 100644 Binary files a/assets/datas/geoip/gi.srs and b/assets/datas/geoip/gi.srs differ diff --git a/assets/datas/geoip/github.srs b/assets/datas/geoip/github.srs index 05d2c93..247fa75 100644 Binary files a/assets/datas/geoip/github.srs and b/assets/datas/geoip/github.srs differ diff --git a/assets/datas/geoip/gl.srs b/assets/datas/geoip/gl.srs index f1a2749..63c9531 100644 Binary files a/assets/datas/geoip/gl.srs and b/assets/datas/geoip/gl.srs differ diff --git a/assets/datas/geoip/gm.srs b/assets/datas/geoip/gm.srs index aa8be3a..9155db8 100644 Binary files a/assets/datas/geoip/gm.srs and b/assets/datas/geoip/gm.srs differ diff --git a/assets/datas/geoip/gn.srs b/assets/datas/geoip/gn.srs index 6bb5d32..bc8c578 100644 Binary files a/assets/datas/geoip/gn.srs and b/assets/datas/geoip/gn.srs differ diff --git a/assets/datas/geoip/google.srs b/assets/datas/geoip/google.srs index 36a0e53..6560ca3 100644 Binary files a/assets/datas/geoip/google.srs and b/assets/datas/geoip/google.srs differ diff --git a/assets/datas/geoip/gp.srs b/assets/datas/geoip/gp.srs index eefdee8..d9f1731 100644 Binary files a/assets/datas/geoip/gp.srs and b/assets/datas/geoip/gp.srs differ diff --git a/assets/datas/geoip/gq.srs b/assets/datas/geoip/gq.srs index 8b16ea2..27afa58 100644 Binary files a/assets/datas/geoip/gq.srs and b/assets/datas/geoip/gq.srs differ diff --git a/assets/datas/geoip/gr.srs b/assets/datas/geoip/gr.srs index 57d8c12..da6604b 100644 Binary files a/assets/datas/geoip/gr.srs and b/assets/datas/geoip/gr.srs differ diff --git a/assets/datas/geoip/gs.srs b/assets/datas/geoip/gs.srs index 6c67916..e81b629 100644 Binary files a/assets/datas/geoip/gs.srs and b/assets/datas/geoip/gs.srs differ diff --git a/assets/datas/geoip/gt.srs b/assets/datas/geoip/gt.srs index ff76e6f..ace6500 100644 Binary files a/assets/datas/geoip/gt.srs and b/assets/datas/geoip/gt.srs differ diff --git a/assets/datas/geoip/gu.srs b/assets/datas/geoip/gu.srs index 41a409c..9436ba3 100644 Binary files a/assets/datas/geoip/gu.srs and b/assets/datas/geoip/gu.srs differ diff --git a/assets/datas/geoip/gw.srs b/assets/datas/geoip/gw.srs index 9619a3b..6a6aa9f 100644 Binary files a/assets/datas/geoip/gw.srs and b/assets/datas/geoip/gw.srs differ diff --git a/assets/datas/geoip/gy.srs b/assets/datas/geoip/gy.srs index 088ee71..7c252d7 100644 Binary files a/assets/datas/geoip/gy.srs and b/assets/datas/geoip/gy.srs differ diff --git a/assets/datas/geoip/hk.srs b/assets/datas/geoip/hk.srs index cb03135..5bcee52 100644 Binary files a/assets/datas/geoip/hk.srs and b/assets/datas/geoip/hk.srs differ diff --git a/assets/datas/geoip/hm.srs b/assets/datas/geoip/hm.srs index db16f9d..9cd2c57 100644 Binary files a/assets/datas/geoip/hm.srs and b/assets/datas/geoip/hm.srs differ diff --git a/assets/datas/geoip/hn.srs b/assets/datas/geoip/hn.srs index 83cfb35..38476ad 100644 Binary files a/assets/datas/geoip/hn.srs and b/assets/datas/geoip/hn.srs differ diff --git a/assets/datas/geoip/hr.srs b/assets/datas/geoip/hr.srs index 2eea772..b0679c7 100644 Binary files a/assets/datas/geoip/hr.srs and b/assets/datas/geoip/hr.srs differ diff --git a/assets/datas/geoip/ht.srs b/assets/datas/geoip/ht.srs index 97041a6..7e5a568 100644 Binary files a/assets/datas/geoip/ht.srs and b/assets/datas/geoip/ht.srs differ diff --git a/assets/datas/geoip/hu.srs b/assets/datas/geoip/hu.srs index 0e3bdb5..cb4eb17 100644 Binary files a/assets/datas/geoip/hu.srs and b/assets/datas/geoip/hu.srs differ diff --git a/assets/datas/geoip/id.srs b/assets/datas/geoip/id.srs index b1d5367..35eca10 100644 Binary files a/assets/datas/geoip/id.srs and b/assets/datas/geoip/id.srs differ diff --git a/assets/datas/geoip/ie.srs b/assets/datas/geoip/ie.srs index 548044b..a870b9a 100644 Binary files a/assets/datas/geoip/ie.srs and b/assets/datas/geoip/ie.srs differ diff --git a/assets/datas/geoip/il.srs b/assets/datas/geoip/il.srs index 7c110fd..2d75d06 100644 Binary files a/assets/datas/geoip/il.srs and b/assets/datas/geoip/il.srs differ diff --git a/assets/datas/geoip/im.srs b/assets/datas/geoip/im.srs index 13101d1..20186a0 100644 Binary files a/assets/datas/geoip/im.srs and b/assets/datas/geoip/im.srs differ diff --git a/assets/datas/geoip/in.srs b/assets/datas/geoip/in.srs index d920f0f..4320939 100644 Binary files a/assets/datas/geoip/in.srs and b/assets/datas/geoip/in.srs differ diff --git a/assets/datas/geoip/io.srs b/assets/datas/geoip/io.srs index 8b0c203..80c2a42 100644 Binary files a/assets/datas/geoip/io.srs and b/assets/datas/geoip/io.srs differ diff --git a/assets/datas/geoip/iq.srs b/assets/datas/geoip/iq.srs index 0af5810..361f942 100644 Binary files a/assets/datas/geoip/iq.srs and b/assets/datas/geoip/iq.srs differ diff --git a/assets/datas/geoip/ir.srs b/assets/datas/geoip/ir.srs index c14d985..53e922a 100644 Binary files a/assets/datas/geoip/ir.srs and b/assets/datas/geoip/ir.srs differ diff --git a/assets/datas/geoip/is.srs b/assets/datas/geoip/is.srs index a3dde14..131c1e5 100644 Binary files a/assets/datas/geoip/is.srs and b/assets/datas/geoip/is.srs differ diff --git a/assets/datas/geoip/it.srs b/assets/datas/geoip/it.srs index 2817b3f..d9bc8c7 100644 Binary files a/assets/datas/geoip/it.srs and b/assets/datas/geoip/it.srs differ diff --git a/assets/datas/geoip/je.srs b/assets/datas/geoip/je.srs index 864d007..ce03712 100644 Binary files a/assets/datas/geoip/je.srs and b/assets/datas/geoip/je.srs differ diff --git a/assets/datas/geoip/jm.srs b/assets/datas/geoip/jm.srs index a6728e8..9ae769c 100644 Binary files a/assets/datas/geoip/jm.srs and b/assets/datas/geoip/jm.srs differ diff --git a/assets/datas/geoip/jo.srs b/assets/datas/geoip/jo.srs index 37030a1..1edbfd5 100644 Binary files a/assets/datas/geoip/jo.srs and b/assets/datas/geoip/jo.srs differ diff --git a/assets/datas/geoip/jp.srs b/assets/datas/geoip/jp.srs index 774c9b1..5b79a06 100644 Binary files a/assets/datas/geoip/jp.srs and b/assets/datas/geoip/jp.srs differ diff --git a/assets/datas/geoip/ke.srs b/assets/datas/geoip/ke.srs index a83952a..b596dcb 100644 Binary files a/assets/datas/geoip/ke.srs and b/assets/datas/geoip/ke.srs differ diff --git a/assets/datas/geoip/kg.srs b/assets/datas/geoip/kg.srs index cf80fb9..e79f8c0 100644 Binary files a/assets/datas/geoip/kg.srs and b/assets/datas/geoip/kg.srs differ diff --git a/assets/datas/geoip/kh.srs b/assets/datas/geoip/kh.srs index a36cb2a..52b6f12 100644 Binary files a/assets/datas/geoip/kh.srs and b/assets/datas/geoip/kh.srs differ diff --git a/assets/datas/geoip/ki.srs b/assets/datas/geoip/ki.srs index 0624d8f..1c4daba 100644 Binary files a/assets/datas/geoip/ki.srs and b/assets/datas/geoip/ki.srs differ diff --git a/assets/datas/geoip/km.srs b/assets/datas/geoip/km.srs index 9c09f3b..cb82a9e 100644 Binary files a/assets/datas/geoip/km.srs and b/assets/datas/geoip/km.srs differ diff --git a/assets/datas/geoip/kn.srs b/assets/datas/geoip/kn.srs index 1effe9a..17709ef 100644 Binary files a/assets/datas/geoip/kn.srs and b/assets/datas/geoip/kn.srs differ diff --git a/assets/datas/geoip/kp.srs b/assets/datas/geoip/kp.srs index 5d2f509..a099bdc 100644 Binary files a/assets/datas/geoip/kp.srs and b/assets/datas/geoip/kp.srs differ diff --git a/assets/datas/geoip/kr.srs b/assets/datas/geoip/kr.srs index 4ea24b9..b9f1cd0 100644 Binary files a/assets/datas/geoip/kr.srs and b/assets/datas/geoip/kr.srs differ diff --git a/assets/datas/geoip/kw.srs b/assets/datas/geoip/kw.srs index d19c997..55e08e2 100644 Binary files a/assets/datas/geoip/kw.srs and b/assets/datas/geoip/kw.srs differ diff --git a/assets/datas/geoip/ky.srs b/assets/datas/geoip/ky.srs index 85ba650..6ae4d80 100644 Binary files a/assets/datas/geoip/ky.srs and b/assets/datas/geoip/ky.srs differ diff --git a/assets/datas/geoip/kz.srs b/assets/datas/geoip/kz.srs index c63b616..75c9459 100644 Binary files a/assets/datas/geoip/kz.srs and b/assets/datas/geoip/kz.srs differ diff --git a/assets/datas/geoip/la.srs b/assets/datas/geoip/la.srs index f492944..ee7262a 100644 Binary files a/assets/datas/geoip/la.srs and b/assets/datas/geoip/la.srs differ diff --git a/assets/datas/geoip/lb.srs b/assets/datas/geoip/lb.srs index 9e93e98..671cf9a 100644 Binary files a/assets/datas/geoip/lb.srs and b/assets/datas/geoip/lb.srs differ diff --git a/assets/datas/geoip/lc.srs b/assets/datas/geoip/lc.srs index 85a9c66..38fc74d 100644 Binary files a/assets/datas/geoip/lc.srs and b/assets/datas/geoip/lc.srs differ diff --git a/assets/datas/geoip/li.srs b/assets/datas/geoip/li.srs index 8005096..6e05904 100644 Binary files a/assets/datas/geoip/li.srs and b/assets/datas/geoip/li.srs differ diff --git a/assets/datas/geoip/linode.srs b/assets/datas/geoip/linode.srs index 9530f3c..478e3da 100644 Binary files a/assets/datas/geoip/linode.srs and b/assets/datas/geoip/linode.srs differ diff --git a/assets/datas/geoip/lk.srs b/assets/datas/geoip/lk.srs index 3b85a3d..6f312e3 100644 Binary files a/assets/datas/geoip/lk.srs and b/assets/datas/geoip/lk.srs differ diff --git a/assets/datas/geoip/lr.srs b/assets/datas/geoip/lr.srs index 4caeca2..69ed090 100644 Binary files a/assets/datas/geoip/lr.srs and b/assets/datas/geoip/lr.srs differ diff --git a/assets/datas/geoip/ls.srs b/assets/datas/geoip/ls.srs index c286051..5fcd60c 100644 Binary files a/assets/datas/geoip/ls.srs and b/assets/datas/geoip/ls.srs differ diff --git a/assets/datas/geoip/lt.srs b/assets/datas/geoip/lt.srs index 1464163..30a5c20 100644 Binary files a/assets/datas/geoip/lt.srs and b/assets/datas/geoip/lt.srs differ diff --git a/assets/datas/geoip/lu.srs b/assets/datas/geoip/lu.srs index 6c493f7..a457506 100644 Binary files a/assets/datas/geoip/lu.srs and b/assets/datas/geoip/lu.srs differ diff --git a/assets/datas/geoip/lv.srs b/assets/datas/geoip/lv.srs index 1a8837b..53b45ff 100644 Binary files a/assets/datas/geoip/lv.srs and b/assets/datas/geoip/lv.srs differ diff --git a/assets/datas/geoip/ly.srs b/assets/datas/geoip/ly.srs index 5b0ee81..4e5406d 100644 Binary files a/assets/datas/geoip/ly.srs and b/assets/datas/geoip/ly.srs differ diff --git a/assets/datas/geoip/ma.srs b/assets/datas/geoip/ma.srs index 65d83f9..1eeaf9a 100644 Binary files a/assets/datas/geoip/ma.srs and b/assets/datas/geoip/ma.srs differ diff --git a/assets/datas/geoip/malware.srs b/assets/datas/geoip/malware.srs index f1ca6e5..eec14d2 100644 Binary files a/assets/datas/geoip/malware.srs and b/assets/datas/geoip/malware.srs differ diff --git a/assets/datas/geoip/mc.srs b/assets/datas/geoip/mc.srs index d398691..c11dad6 100644 Binary files a/assets/datas/geoip/mc.srs and b/assets/datas/geoip/mc.srs differ diff --git a/assets/datas/geoip/md.srs b/assets/datas/geoip/md.srs index 419579a..340e3c2 100644 Binary files a/assets/datas/geoip/md.srs and b/assets/datas/geoip/md.srs differ diff --git a/assets/datas/geoip/me.srs b/assets/datas/geoip/me.srs index 906b187..9f43ffe 100644 Binary files a/assets/datas/geoip/me.srs and b/assets/datas/geoip/me.srs differ diff --git a/assets/datas/geoip/mf.srs b/assets/datas/geoip/mf.srs index 0785079..6d4fdce 100644 Binary files a/assets/datas/geoip/mf.srs and b/assets/datas/geoip/mf.srs differ diff --git a/assets/datas/geoip/mg.srs b/assets/datas/geoip/mg.srs index 0c856bd..36898c4 100644 Binary files a/assets/datas/geoip/mg.srs and b/assets/datas/geoip/mg.srs differ diff --git a/assets/datas/geoip/mh.srs b/assets/datas/geoip/mh.srs index 39320dc..e3da92d 100644 Binary files a/assets/datas/geoip/mh.srs and b/assets/datas/geoip/mh.srs differ diff --git a/assets/datas/geoip/microsoft.srs b/assets/datas/geoip/microsoft.srs index 8c41a22..5f3f663 100644 Binary files a/assets/datas/geoip/microsoft.srs and b/assets/datas/geoip/microsoft.srs differ diff --git a/assets/datas/geoip/mk.srs b/assets/datas/geoip/mk.srs index b57a983..46efc66 100644 Binary files a/assets/datas/geoip/mk.srs and b/assets/datas/geoip/mk.srs differ diff --git a/assets/datas/geoip/ml.srs b/assets/datas/geoip/ml.srs index fdb643b..7adb0de 100644 Binary files a/assets/datas/geoip/ml.srs and b/assets/datas/geoip/ml.srs differ diff --git a/assets/datas/geoip/mm.srs b/assets/datas/geoip/mm.srs index 20215bf..af5a6d4 100644 Binary files a/assets/datas/geoip/mm.srs and b/assets/datas/geoip/mm.srs differ diff --git a/assets/datas/geoip/mn.srs b/assets/datas/geoip/mn.srs index 6ed1da4..1338fcd 100644 Binary files a/assets/datas/geoip/mn.srs and b/assets/datas/geoip/mn.srs differ diff --git a/assets/datas/geoip/mo.srs b/assets/datas/geoip/mo.srs index c775113..39657f3 100644 Binary files a/assets/datas/geoip/mo.srs and b/assets/datas/geoip/mo.srs differ diff --git a/assets/datas/geoip/mp.srs b/assets/datas/geoip/mp.srs index e69a4e2..33c4783 100644 Binary files a/assets/datas/geoip/mp.srs and b/assets/datas/geoip/mp.srs differ diff --git a/assets/datas/geoip/mq.srs b/assets/datas/geoip/mq.srs index 9b68e2f..80aa44c 100644 Binary files a/assets/datas/geoip/mq.srs and b/assets/datas/geoip/mq.srs differ diff --git a/assets/datas/geoip/mr.srs b/assets/datas/geoip/mr.srs index d5bc482..cb28d86 100644 Binary files a/assets/datas/geoip/mr.srs and b/assets/datas/geoip/mr.srs differ diff --git a/assets/datas/geoip/ms.srs b/assets/datas/geoip/ms.srs index a9c21cd..ccdb5a4 100644 Binary files a/assets/datas/geoip/ms.srs and b/assets/datas/geoip/ms.srs differ diff --git a/assets/datas/geoip/mt.srs b/assets/datas/geoip/mt.srs index 271da33..fa9efac 100644 Binary files a/assets/datas/geoip/mt.srs and b/assets/datas/geoip/mt.srs differ diff --git a/assets/datas/geoip/mu.srs b/assets/datas/geoip/mu.srs index 980aa10..f13550c 100644 Binary files a/assets/datas/geoip/mu.srs and b/assets/datas/geoip/mu.srs differ diff --git a/assets/datas/geoip/mv.srs b/assets/datas/geoip/mv.srs index 0cc7434..5bf56fa 100644 Binary files a/assets/datas/geoip/mv.srs and b/assets/datas/geoip/mv.srs differ diff --git a/assets/datas/geoip/mw.srs b/assets/datas/geoip/mw.srs index d023ecf..bb92fa9 100644 Binary files a/assets/datas/geoip/mw.srs and b/assets/datas/geoip/mw.srs differ diff --git a/assets/datas/geoip/mx.srs b/assets/datas/geoip/mx.srs index 77e6336..56cc5a3 100644 Binary files a/assets/datas/geoip/mx.srs and b/assets/datas/geoip/mx.srs differ diff --git a/assets/datas/geoip/my.srs b/assets/datas/geoip/my.srs index 32715a2..a0872a9 100644 Binary files a/assets/datas/geoip/my.srs and b/assets/datas/geoip/my.srs differ diff --git a/assets/datas/geoip/mz.srs b/assets/datas/geoip/mz.srs index aab90bf..b3eaf0c 100644 Binary files a/assets/datas/geoip/mz.srs and b/assets/datas/geoip/mz.srs differ diff --git a/assets/datas/geoip/na.srs b/assets/datas/geoip/na.srs index 458f6ac..30dbc29 100644 Binary files a/assets/datas/geoip/na.srs and b/assets/datas/geoip/na.srs differ diff --git a/assets/datas/geoip/nc.srs b/assets/datas/geoip/nc.srs index 3f2fb2b..3bda212 100644 Binary files a/assets/datas/geoip/nc.srs and b/assets/datas/geoip/nc.srs differ diff --git a/assets/datas/geoip/ne.srs b/assets/datas/geoip/ne.srs index 805b40b..7fdbbd0 100644 Binary files a/assets/datas/geoip/ne.srs and b/assets/datas/geoip/ne.srs differ diff --git a/assets/datas/geoip/nf.srs b/assets/datas/geoip/nf.srs index 323eb9c..3dbb947 100644 Binary files a/assets/datas/geoip/nf.srs and b/assets/datas/geoip/nf.srs differ diff --git a/assets/datas/geoip/ng.srs b/assets/datas/geoip/ng.srs index abf5e8a..69e79a9 100644 Binary files a/assets/datas/geoip/ng.srs and b/assets/datas/geoip/ng.srs differ diff --git a/assets/datas/geoip/ni.srs b/assets/datas/geoip/ni.srs index 083d37e..8a09a22 100644 Binary files a/assets/datas/geoip/ni.srs and b/assets/datas/geoip/ni.srs differ diff --git a/assets/datas/geoip/nl.srs b/assets/datas/geoip/nl.srs index 0bb0ba1..b30a96e 100644 Binary files a/assets/datas/geoip/nl.srs and b/assets/datas/geoip/nl.srs differ diff --git a/assets/datas/geoip/no.srs b/assets/datas/geoip/no.srs index 8f4141d..a5b1260 100644 Binary files a/assets/datas/geoip/no.srs and b/assets/datas/geoip/no.srs differ diff --git a/assets/datas/geoip/np.srs b/assets/datas/geoip/np.srs index b72c380..8592410 100644 Binary files a/assets/datas/geoip/np.srs and b/assets/datas/geoip/np.srs differ diff --git a/assets/datas/geoip/nr.srs b/assets/datas/geoip/nr.srs index 4f58d0e..785c59e 100644 Binary files a/assets/datas/geoip/nr.srs and b/assets/datas/geoip/nr.srs differ diff --git a/assets/datas/geoip/nu.srs b/assets/datas/geoip/nu.srs index 4af8c2a..98b8507 100644 Binary files a/assets/datas/geoip/nu.srs and b/assets/datas/geoip/nu.srs differ diff --git a/assets/datas/geoip/nz.srs b/assets/datas/geoip/nz.srs index a13180f..4aa2806 100644 Binary files a/assets/datas/geoip/nz.srs and b/assets/datas/geoip/nz.srs differ diff --git a/assets/datas/geoip/om.srs b/assets/datas/geoip/om.srs index c2e846a..1cc262c 100644 Binary files a/assets/datas/geoip/om.srs and b/assets/datas/geoip/om.srs differ diff --git a/assets/datas/geoip/oracle.srs b/assets/datas/geoip/oracle.srs index f8ce73e..d3a50fb 100644 Binary files a/assets/datas/geoip/oracle.srs and b/assets/datas/geoip/oracle.srs differ diff --git a/assets/datas/geoip/pa.srs b/assets/datas/geoip/pa.srs index 408f671..14303f6 100644 Binary files a/assets/datas/geoip/pa.srs and b/assets/datas/geoip/pa.srs differ diff --git a/assets/datas/geoip/pe.srs b/assets/datas/geoip/pe.srs index c1153b7..1dccca9 100644 Binary files a/assets/datas/geoip/pe.srs and b/assets/datas/geoip/pe.srs differ diff --git a/assets/datas/geoip/pf.srs b/assets/datas/geoip/pf.srs index 5716990..165949e 100644 Binary files a/assets/datas/geoip/pf.srs and b/assets/datas/geoip/pf.srs differ diff --git a/assets/datas/geoip/pg.srs b/assets/datas/geoip/pg.srs index 55a697a..adef23d 100644 Binary files a/assets/datas/geoip/pg.srs and b/assets/datas/geoip/pg.srs differ diff --git a/assets/datas/geoip/ph.srs b/assets/datas/geoip/ph.srs index 5a14de4..0ec24ed 100644 Binary files a/assets/datas/geoip/ph.srs and b/assets/datas/geoip/ph.srs differ diff --git a/assets/datas/geoip/pk.srs b/assets/datas/geoip/pk.srs index c44ba1c..f0ff7f2 100644 Binary files a/assets/datas/geoip/pk.srs and b/assets/datas/geoip/pk.srs differ diff --git a/assets/datas/geoip/pl.srs b/assets/datas/geoip/pl.srs index 8998c2f..7d668c0 100644 Binary files a/assets/datas/geoip/pl.srs and b/assets/datas/geoip/pl.srs differ diff --git a/assets/datas/geoip/pm.srs b/assets/datas/geoip/pm.srs index dd0896d..97ea3b3 100644 Binary files a/assets/datas/geoip/pm.srs and b/assets/datas/geoip/pm.srs differ diff --git a/assets/datas/geoip/pn.srs b/assets/datas/geoip/pn.srs index 058b2ad..3d98e9c 100644 Binary files a/assets/datas/geoip/pn.srs and b/assets/datas/geoip/pn.srs differ diff --git a/assets/datas/geoip/pr.srs b/assets/datas/geoip/pr.srs index 194d640..c72236a 100644 Binary files a/assets/datas/geoip/pr.srs and b/assets/datas/geoip/pr.srs differ diff --git a/assets/datas/geoip/ps.srs b/assets/datas/geoip/ps.srs index 529701f..b2f4162 100644 Binary files a/assets/datas/geoip/ps.srs and b/assets/datas/geoip/ps.srs differ diff --git a/assets/datas/geoip/pt.srs b/assets/datas/geoip/pt.srs index 1a390d6..2e3468e 100644 Binary files a/assets/datas/geoip/pt.srs and b/assets/datas/geoip/pt.srs differ diff --git a/assets/datas/geoip/pw.srs b/assets/datas/geoip/pw.srs index eb43897..470dfd9 100644 Binary files a/assets/datas/geoip/pw.srs and b/assets/datas/geoip/pw.srs differ diff --git a/assets/datas/geoip/py.srs b/assets/datas/geoip/py.srs index c04a7fd..d8a8766 100644 Binary files a/assets/datas/geoip/py.srs and b/assets/datas/geoip/py.srs differ diff --git a/assets/datas/geoip/qa.srs b/assets/datas/geoip/qa.srs index be5825d..0a947f8 100644 Binary files a/assets/datas/geoip/qa.srs and b/assets/datas/geoip/qa.srs differ diff --git a/assets/datas/geoip/re.srs b/assets/datas/geoip/re.srs index 903d62d..151e5aa 100644 Binary files a/assets/datas/geoip/re.srs and b/assets/datas/geoip/re.srs differ diff --git a/assets/datas/geoip/ro.srs b/assets/datas/geoip/ro.srs index 4c8a14f..ab49f90 100644 Binary files a/assets/datas/geoip/ro.srs and b/assets/datas/geoip/ro.srs differ diff --git a/assets/datas/geoip/rs.srs b/assets/datas/geoip/rs.srs index 1ab36f1..e88a0c0 100644 Binary files a/assets/datas/geoip/rs.srs and b/assets/datas/geoip/rs.srs differ diff --git a/assets/datas/geoip/ru.srs b/assets/datas/geoip/ru.srs index 02a4c7c..3b019b3 100644 Binary files a/assets/datas/geoip/ru.srs and b/assets/datas/geoip/ru.srs differ diff --git a/assets/datas/geoip/rw.srs b/assets/datas/geoip/rw.srs index 222e808..51fae62 100644 Binary files a/assets/datas/geoip/rw.srs and b/assets/datas/geoip/rw.srs differ diff --git a/assets/datas/geoip/sa.srs b/assets/datas/geoip/sa.srs index c2a60d0..f60bc56 100644 Binary files a/assets/datas/geoip/sa.srs and b/assets/datas/geoip/sa.srs differ diff --git a/assets/datas/geoip/sb.srs b/assets/datas/geoip/sb.srs index 1a4539a..4086d08 100644 Binary files a/assets/datas/geoip/sb.srs and b/assets/datas/geoip/sb.srs differ diff --git a/assets/datas/geoip/sc.srs b/assets/datas/geoip/sc.srs index cdefc59..a72cd51 100644 Binary files a/assets/datas/geoip/sc.srs and b/assets/datas/geoip/sc.srs differ diff --git a/assets/datas/geoip/sd.srs b/assets/datas/geoip/sd.srs index 5e1bc4c..ba0be02 100644 Binary files a/assets/datas/geoip/sd.srs and b/assets/datas/geoip/sd.srs differ diff --git a/assets/datas/geoip/se.srs b/assets/datas/geoip/se.srs index 7aacea2..173c53a 100644 Binary files a/assets/datas/geoip/se.srs and b/assets/datas/geoip/se.srs differ diff --git a/assets/datas/geoip/sg.srs b/assets/datas/geoip/sg.srs index 76d2db6..d8420b0 100644 Binary files a/assets/datas/geoip/sg.srs and b/assets/datas/geoip/sg.srs differ diff --git a/assets/datas/geoip/sh.srs b/assets/datas/geoip/sh.srs index 1f6ddf0..bfa714a 100644 Binary files a/assets/datas/geoip/sh.srs and b/assets/datas/geoip/sh.srs differ diff --git a/assets/datas/geoip/si.srs b/assets/datas/geoip/si.srs index 7dade03..ea017b9 100644 Binary files a/assets/datas/geoip/si.srs and b/assets/datas/geoip/si.srs differ diff --git a/assets/datas/geoip/sj.srs b/assets/datas/geoip/sj.srs index 8766459..60e4cb8 100644 Binary files a/assets/datas/geoip/sj.srs and b/assets/datas/geoip/sj.srs differ diff --git a/assets/datas/geoip/sk.srs b/assets/datas/geoip/sk.srs index 5ebbda9..57d36e5 100644 Binary files a/assets/datas/geoip/sk.srs and b/assets/datas/geoip/sk.srs differ diff --git a/assets/datas/geoip/sl.srs b/assets/datas/geoip/sl.srs index 6bb0bb5..9270489 100644 Binary files a/assets/datas/geoip/sl.srs and b/assets/datas/geoip/sl.srs differ diff --git a/assets/datas/geoip/sm.srs b/assets/datas/geoip/sm.srs index 0f280d3..0c74859 100644 Binary files a/assets/datas/geoip/sm.srs and b/assets/datas/geoip/sm.srs differ diff --git a/assets/datas/geoip/sn.srs b/assets/datas/geoip/sn.srs index 9742044..eeebb13 100644 Binary files a/assets/datas/geoip/sn.srs and b/assets/datas/geoip/sn.srs differ diff --git a/assets/datas/geoip/so.srs b/assets/datas/geoip/so.srs index e3c83e2..499bddb 100644 Binary files a/assets/datas/geoip/so.srs and b/assets/datas/geoip/so.srs differ diff --git a/assets/datas/geoip/sr.srs b/assets/datas/geoip/sr.srs index 22dc506..aa61894 100644 Binary files a/assets/datas/geoip/sr.srs and b/assets/datas/geoip/sr.srs differ diff --git a/assets/datas/geoip/ss.srs b/assets/datas/geoip/ss.srs index d1f4889..d55410c 100644 Binary files a/assets/datas/geoip/ss.srs and b/assets/datas/geoip/ss.srs differ diff --git a/assets/datas/geoip/st.srs b/assets/datas/geoip/st.srs index 96481c6..1154210 100644 Binary files a/assets/datas/geoip/st.srs and b/assets/datas/geoip/st.srs differ diff --git a/assets/datas/geoip/sv.srs b/assets/datas/geoip/sv.srs index f8d3f36..3cacb43 100644 Binary files a/assets/datas/geoip/sv.srs and b/assets/datas/geoip/sv.srs differ diff --git a/assets/datas/geoip/sx.srs b/assets/datas/geoip/sx.srs index f79653d..70379af 100644 Binary files a/assets/datas/geoip/sx.srs and b/assets/datas/geoip/sx.srs differ diff --git a/assets/datas/geoip/sy.srs b/assets/datas/geoip/sy.srs index 9f1d8d9..7e17e13 100644 Binary files a/assets/datas/geoip/sy.srs and b/assets/datas/geoip/sy.srs differ diff --git a/assets/datas/geoip/sz.srs b/assets/datas/geoip/sz.srs index 75acd75..e2072c2 100644 Binary files a/assets/datas/geoip/sz.srs and b/assets/datas/geoip/sz.srs differ diff --git a/assets/datas/geoip/tc.srs b/assets/datas/geoip/tc.srs index 6f3572b..158f088 100644 Binary files a/assets/datas/geoip/tc.srs and b/assets/datas/geoip/tc.srs differ diff --git a/assets/datas/geoip/td.srs b/assets/datas/geoip/td.srs index 6d06ab5..13d1f10 100644 Binary files a/assets/datas/geoip/td.srs and b/assets/datas/geoip/td.srs differ diff --git a/assets/datas/geoip/tf.srs b/assets/datas/geoip/tf.srs index 97f043a..184bff2 100644 Binary files a/assets/datas/geoip/tf.srs and b/assets/datas/geoip/tf.srs differ diff --git a/assets/datas/geoip/tg.srs b/assets/datas/geoip/tg.srs index 13c4227..ae84230 100644 Binary files a/assets/datas/geoip/tg.srs and b/assets/datas/geoip/tg.srs differ diff --git a/assets/datas/geoip/th.srs b/assets/datas/geoip/th.srs index fd0d6a4..622ccd9 100644 Binary files a/assets/datas/geoip/th.srs and b/assets/datas/geoip/th.srs differ diff --git a/assets/datas/geoip/tj.srs b/assets/datas/geoip/tj.srs index 7b06e3d..72f4d71 100644 Binary files a/assets/datas/geoip/tj.srs and b/assets/datas/geoip/tj.srs differ diff --git a/assets/datas/geoip/tk.srs b/assets/datas/geoip/tk.srs index c2121dc..b7e6d67 100644 Binary files a/assets/datas/geoip/tk.srs and b/assets/datas/geoip/tk.srs differ diff --git a/assets/datas/geoip/tl.srs b/assets/datas/geoip/tl.srs index 2c22717..c3408a0 100644 Binary files a/assets/datas/geoip/tl.srs and b/assets/datas/geoip/tl.srs differ diff --git a/assets/datas/geoip/tm.srs b/assets/datas/geoip/tm.srs index 69320a5..e9e7c30 100644 Binary files a/assets/datas/geoip/tm.srs and b/assets/datas/geoip/tm.srs differ diff --git a/assets/datas/geoip/tn.srs b/assets/datas/geoip/tn.srs index ca85e63..73f3a1c 100644 Binary files a/assets/datas/geoip/tn.srs and b/assets/datas/geoip/tn.srs differ diff --git a/assets/datas/geoip/to.srs b/assets/datas/geoip/to.srs index 270aca9..98a4273 100644 Binary files a/assets/datas/geoip/to.srs and b/assets/datas/geoip/to.srs differ diff --git a/assets/datas/geoip/tr.srs b/assets/datas/geoip/tr.srs index ca16803..d674f21 100644 Binary files a/assets/datas/geoip/tr.srs and b/assets/datas/geoip/tr.srs differ diff --git a/assets/datas/geoip/tt.srs b/assets/datas/geoip/tt.srs index 198776f..fe2b265 100644 Binary files a/assets/datas/geoip/tt.srs and b/assets/datas/geoip/tt.srs differ diff --git a/assets/datas/geoip/tv.srs b/assets/datas/geoip/tv.srs index 5b95926..1ee0ebd 100644 Binary files a/assets/datas/geoip/tv.srs and b/assets/datas/geoip/tv.srs differ diff --git a/assets/datas/geoip/tw.srs b/assets/datas/geoip/tw.srs index f8559b7..6fb90f1 100644 Binary files a/assets/datas/geoip/tw.srs and b/assets/datas/geoip/tw.srs differ diff --git a/assets/datas/geoip/tz.srs b/assets/datas/geoip/tz.srs index 3440d94..5104338 100644 Binary files a/assets/datas/geoip/tz.srs and b/assets/datas/geoip/tz.srs differ diff --git a/assets/datas/geoip/ua.srs b/assets/datas/geoip/ua.srs index a688b71..7549e25 100644 Binary files a/assets/datas/geoip/ua.srs and b/assets/datas/geoip/ua.srs differ diff --git a/assets/datas/geoip/ug.srs b/assets/datas/geoip/ug.srs index 1de14a4..1292488 100644 Binary files a/assets/datas/geoip/ug.srs and b/assets/datas/geoip/ug.srs differ diff --git a/assets/datas/geoip/um.srs b/assets/datas/geoip/um.srs index f8f22df..5feced1 100644 Binary files a/assets/datas/geoip/um.srs and b/assets/datas/geoip/um.srs differ diff --git a/assets/datas/geoip/us.srs b/assets/datas/geoip/us.srs index 6586e31..a76511e 100644 Binary files a/assets/datas/geoip/us.srs and b/assets/datas/geoip/us.srs differ diff --git a/assets/datas/geoip/uy.srs b/assets/datas/geoip/uy.srs index 807e8f9..ee7645d 100644 Binary files a/assets/datas/geoip/uy.srs and b/assets/datas/geoip/uy.srs differ diff --git a/assets/datas/geoip/uz.srs b/assets/datas/geoip/uz.srs index 4044685..4431ed7 100644 Binary files a/assets/datas/geoip/uz.srs and b/assets/datas/geoip/uz.srs differ diff --git a/assets/datas/geoip/va.srs b/assets/datas/geoip/va.srs index 9c3c46a..e4d42c0 100644 Binary files a/assets/datas/geoip/va.srs and b/assets/datas/geoip/va.srs differ diff --git a/assets/datas/geoip/vc.srs b/assets/datas/geoip/vc.srs index 6b8d457..2f3e7de 100644 Binary files a/assets/datas/geoip/vc.srs and b/assets/datas/geoip/vc.srs differ diff --git a/assets/datas/geoip/ve.srs b/assets/datas/geoip/ve.srs index 94944ae..20461dd 100644 Binary files a/assets/datas/geoip/ve.srs and b/assets/datas/geoip/ve.srs differ diff --git a/assets/datas/geoip/vg.srs b/assets/datas/geoip/vg.srs index dfae655..6e145c4 100644 Binary files a/assets/datas/geoip/vg.srs and b/assets/datas/geoip/vg.srs differ diff --git a/assets/datas/geoip/vi.srs b/assets/datas/geoip/vi.srs index 6af95f7..bd96e78 100644 Binary files a/assets/datas/geoip/vi.srs and b/assets/datas/geoip/vi.srs differ diff --git a/assets/datas/geoip/vn.srs b/assets/datas/geoip/vn.srs index f910574..b906770 100644 Binary files a/assets/datas/geoip/vn.srs and b/assets/datas/geoip/vn.srs differ diff --git a/assets/datas/geoip/vu.srs b/assets/datas/geoip/vu.srs index 7d7fed6..9c438bb 100644 Binary files a/assets/datas/geoip/vu.srs and b/assets/datas/geoip/vu.srs differ diff --git a/assets/datas/geoip/wf.srs b/assets/datas/geoip/wf.srs index 216d9fa..c9954a5 100644 Binary files a/assets/datas/geoip/wf.srs and b/assets/datas/geoip/wf.srs differ diff --git a/assets/datas/geoip/ws.srs b/assets/datas/geoip/ws.srs index 2d048c7..3ea8bdf 100644 Binary files a/assets/datas/geoip/ws.srs and b/assets/datas/geoip/ws.srs differ diff --git a/assets/datas/geoip/xk.srs b/assets/datas/geoip/xk.srs index 2690fdc..c39186d 100644 Binary files a/assets/datas/geoip/xk.srs and b/assets/datas/geoip/xk.srs differ diff --git a/assets/datas/geoip/ye.srs b/assets/datas/geoip/ye.srs index b69d6ac..149cce3 100644 Binary files a/assets/datas/geoip/ye.srs and b/assets/datas/geoip/ye.srs differ diff --git a/assets/datas/geoip/yt.srs b/assets/datas/geoip/yt.srs index 0d77fc2..f6b0d6a 100644 Binary files a/assets/datas/geoip/yt.srs and b/assets/datas/geoip/yt.srs differ diff --git a/assets/datas/geoip/za.srs b/assets/datas/geoip/za.srs index ab1ea12..36424d5 100644 Binary files a/assets/datas/geoip/za.srs and b/assets/datas/geoip/za.srs differ diff --git a/assets/datas/geoip/zm.srs b/assets/datas/geoip/zm.srs index c435d3f..f76f2eb 100644 Binary files a/assets/datas/geoip/zm.srs and b/assets/datas/geoip/zm.srs differ diff --git a/assets/datas/geoip/zw.srs b/assets/datas/geoip/zw.srs index 84bd27a..762d5a8 100644 Binary files a/assets/datas/geoip/zw.srs and b/assets/datas/geoip/zw.srs differ diff --git a/assets/datas/geosite/ads.srs b/assets/datas/geosite/ads.srs index 8377313..9d0a2d4 100644 Binary files a/assets/datas/geosite/ads.srs and b/assets/datas/geosite/ads.srs differ diff --git a/assets/datas/geosite/apple-cn.srs b/assets/datas/geosite/apple-cn.srs index 4f62110..ddf7884 100644 Binary files a/assets/datas/geosite/apple-cn.srs and b/assets/datas/geosite/apple-cn.srs differ diff --git a/assets/datas/geosite/category-companies.srs b/assets/datas/geosite/category-companies.srs index b09487f..864c185 100644 Binary files a/assets/datas/geosite/category-companies.srs and b/assets/datas/geosite/category-companies.srs differ diff --git a/assets/datas/geosite/category-companies@cn.srs b/assets/datas/geosite/category-companies@cn.srs index b3201f3..7e813cb 100644 Binary files a/assets/datas/geosite/category-companies@cn.srs and b/assets/datas/geosite/category-companies@cn.srs differ diff --git a/assets/datas/geosite/category-dev.srs b/assets/datas/geosite/category-dev.srs index 135d54e..a45eaa1 100644 Binary files a/assets/datas/geosite/category-dev.srs and b/assets/datas/geosite/category-dev.srs differ diff --git a/assets/datas/geosite/category-entertainment.srs b/assets/datas/geosite/category-entertainment.srs index cddda1a..33dc636 100644 Binary files a/assets/datas/geosite/category-entertainment.srs and b/assets/datas/geosite/category-entertainment.srs differ diff --git a/assets/datas/geosite/category-ir.srs b/assets/datas/geosite/category-ir.srs index 4a24a6f..f24f4a6 100644 Binary files a/assets/datas/geosite/category-ir.srs and b/assets/datas/geosite/category-ir.srs differ diff --git a/assets/datas/geosite/category-porn.srs b/assets/datas/geosite/category-porn.srs index 2588d4c..076dd70 100644 Binary files a/assets/datas/geosite/category-porn.srs and b/assets/datas/geosite/category-porn.srs differ diff --git a/assets/datas/geosite/cn.srs b/assets/datas/geosite/cn.srs index 8eb03d3..057a55d 100644 Binary files a/assets/datas/geosite/cn.srs and b/assets/datas/geosite/cn.srs differ diff --git a/assets/datas/geosite/geolocation-!cn.srs b/assets/datas/geosite/geolocation-!cn.srs index 431d6c7..229ae47 100644 Binary files a/assets/datas/geosite/geolocation-!cn.srs and b/assets/datas/geosite/geolocation-!cn.srs differ diff --git a/assets/datas/geosite/geolocation-cn.srs b/assets/datas/geosite/geolocation-cn.srs index ee24389..016936f 100644 Binary files a/assets/datas/geosite/geolocation-cn.srs and b/assets/datas/geosite/geolocation-cn.srs differ diff --git a/assets/datas/geosite/hetzner.srs b/assets/datas/geosite/hetzner.srs index c286716..316e3c5 100644 Binary files a/assets/datas/geosite/hetzner.srs and b/assets/datas/geosite/hetzner.srs differ diff --git a/assets/datas/geosite/ir.srs b/assets/datas/geosite/ir.srs index e620007..a0c1e90 100644 Binary files a/assets/datas/geosite/ir.srs and b/assets/datas/geosite/ir.srs differ diff --git a/assets/datas/geosite/malware.srs b/assets/datas/geosite/malware.srs index 616d1fa..7f85d16 100644 Binary files a/assets/datas/geosite/malware.srs and b/assets/datas/geosite/malware.srs differ diff --git a/assets/datas/geosite/nsfw.srs b/assets/datas/geosite/nsfw.srs index 020cc37..a895cf3 100644 Binary files a/assets/datas/geosite/nsfw.srs and b/assets/datas/geosite/nsfw.srs differ diff --git a/assets/datas/geosite/phishing.srs b/assets/datas/geosite/phishing.srs index 0027da9..d00cfe6 100644 Binary files a/assets/datas/geosite/phishing.srs and b/assets/datas/geosite/phishing.srs differ diff --git a/assets/datas/geosite/tracker.srs b/assets/datas/geosite/tracker.srs index a76ecf3..fca13de 100644 Binary files a/assets/datas/geosite/tracker.srs and b/assets/datas/geosite/tracker.srs differ diff --git a/lib/i18n/strings.g.dart b/lib/i18n/strings.g.dart index 1d81971..8180381 100644 --- a/lib/i18n/strings.g.dart +++ b/lib/i18n/strings.g.dart @@ -1,45 +1,137 @@ /// Generated file. Do not edit. /// -/// Original: lib/i18n +/// Source: lib/i18n /// To regenerate, run: `dart run slang` /// /// Locales: 5 -/// Strings: 2205 (441 per locale) +/// Strings: 2255 (451 per locale) /// -/// Built on 2024-10-10 at 06:50 UTC +/// Built on 2024-10-31 at 05:18 UTC // coverage:ignore-file -// ignore_for_file: type=lint +// ignore_for_file: type=lint, unused_import import 'package:flutter/widgets.dart'; -import 'package:slang/builder/model/node.dart'; +import 'package:intl/intl.dart'; +import 'package:slang/generated.dart'; import 'package:slang_flutter/slang_flutter.dart'; export 'package:slang_flutter/slang_flutter.dart'; -const AppLocale _baseLocale = AppLocale.en; +import 'strings_ar.g.dart' deferred as l_ar; +import 'strings_fa.g.dart' deferred as l_fa; +import 'strings_ru.g.dart' deferred as l_ru; +import 'strings_zh_CN.g.dart' deferred as l_zh_CN; +part 'strings_en.g.dart'; -/// Supported locales, see extension methods below. +/// Supported locales. /// /// Usage: /// - LocaleSettings.setLocale(AppLocale.en) // set locale /// - Locale locale = AppLocale.en.flutterLocale // get flutter locale from enum /// - if (LocaleSettings.currentLocale == AppLocale.en) // locale check enum AppLocale with BaseAppLocale { - en(languageCode: 'en', build: Translations.build), - ar(languageCode: 'ar', build: _StringsAr.build), - fa(languageCode: 'fa', build: _StringsFa.build), - ru(languageCode: 'ru', build: _StringsRu.build), - zhCn(languageCode: 'zh', countryCode: 'CN', build: _StringsZhCn.build); - - const AppLocale({required this.languageCode, this.scriptCode, this.countryCode, required this.build}); // ignore: unused_element + en(languageCode: 'en'), + ar(languageCode: 'ar'), + fa(languageCode: 'fa'), + ru(languageCode: 'ru'), + zhCn(languageCode: 'zh', countryCode: 'CN'); + + const AppLocale({ + required this.languageCode, + this.scriptCode, // ignore: unused_element + this.countryCode, // ignore: unused_element + }); @override final String languageCode; @override final String? scriptCode; @override final String? countryCode; - @override final TranslationBuilder build; + + @override + Future build({ + Map? overrides, + PluralResolver? cardinalResolver, + PluralResolver? ordinalResolver, + }) async { + switch (this) { + case AppLocale.en: + return TranslationsEn( + overrides: overrides, + cardinalResolver: cardinalResolver, + ordinalResolver: ordinalResolver, + ); + case AppLocale.ar: + await l_ar.loadLibrary(); + return l_ar.TranslationsAr( + overrides: overrides, + cardinalResolver: cardinalResolver, + ordinalResolver: ordinalResolver, + ); + case AppLocale.fa: + await l_fa.loadLibrary(); + return l_fa.TranslationsFa( + overrides: overrides, + cardinalResolver: cardinalResolver, + ordinalResolver: ordinalResolver, + ); + case AppLocale.ru: + await l_ru.loadLibrary(); + return l_ru.TranslationsRu( + overrides: overrides, + cardinalResolver: cardinalResolver, + ordinalResolver: ordinalResolver, + ); + case AppLocale.zhCn: + await l_zh_CN.loadLibrary(); + return l_zh_CN.TranslationsZhCn( + overrides: overrides, + cardinalResolver: cardinalResolver, + ordinalResolver: ordinalResolver, + ); + } + } + + @override + Translations buildSync({ + Map? overrides, + PluralResolver? cardinalResolver, + PluralResolver? ordinalResolver, + }) { + switch (this) { + case AppLocale.en: + return TranslationsEn( + overrides: overrides, + cardinalResolver: cardinalResolver, + ordinalResolver: ordinalResolver, + ); + case AppLocale.ar: + return l_ar.TranslationsAr( + overrides: overrides, + cardinalResolver: cardinalResolver, + ordinalResolver: ordinalResolver, + ); + case AppLocale.fa: + return l_fa.TranslationsFa( + overrides: overrides, + cardinalResolver: cardinalResolver, + ordinalResolver: ordinalResolver, + ); + case AppLocale.ru: + return l_ru.TranslationsRu( + overrides: overrides, + cardinalResolver: cardinalResolver, + ordinalResolver: ordinalResolver, + ); + case AppLocale.zhCn: + return l_zh_CN.TranslationsZhCn( + overrides: overrides, + cardinalResolver: cardinalResolver, + ordinalResolver: ordinalResolver, + ); + } + } /// Gets current instance managed by [LocaleSettings]. - Translations get translations => LocaleSettings.instance.translationMap[this]!; + Translations get translations => LocaleSettings.instance.getTranslations(this); } /// Method A: Simple @@ -85,19 +177,31 @@ extension BuildContextTranslationsExtension on BuildContext { /// Manages all translation instances and the current locale class LocaleSettings extends BaseFlutterLocaleSettings { - LocaleSettings._() : super(utils: AppLocaleUtils.instance); + LocaleSettings._() : super( + utils: AppLocaleUtils.instance, + lazy: true, + ); static final instance = LocaleSettings._(); // static aliases (checkout base methods for documentation) static AppLocale get currentLocale => instance.currentLocale; static Stream getLocaleStream() => instance.getLocaleStream(); - static AppLocale setLocale(AppLocale locale, {bool? listenToDeviceLocale = false}) => instance.setLocale(locale, listenToDeviceLocale: listenToDeviceLocale); - static AppLocale setLocaleRaw(String rawLocale, {bool? listenToDeviceLocale = false}) => instance.setLocaleRaw(rawLocale, listenToDeviceLocale: listenToDeviceLocale); - static AppLocale useDeviceLocale() => instance.useDeviceLocale(); - @Deprecated('Use [AppLocaleUtils.supportedLocales]') static List get supportedLocales => instance.supportedLocales; - @Deprecated('Use [AppLocaleUtils.supportedLocalesRaw]') static List get supportedLocalesRaw => instance.supportedLocalesRaw; - static void setPluralResolver({String? language, AppLocale? locale, PluralResolver? cardinalResolver, PluralResolver? ordinalResolver}) => instance.setPluralResolver( + static Future setLocale(AppLocale locale, {bool? listenToDeviceLocale = false}) => instance.setLocale(locale, listenToDeviceLocale: listenToDeviceLocale); + static Future setLocaleRaw(String rawLocale, {bool? listenToDeviceLocale = false}) => instance.setLocaleRaw(rawLocale, listenToDeviceLocale: listenToDeviceLocale); + static Future useDeviceLocale() => instance.useDeviceLocale(); + static Future setPluralResolver({String? language, AppLocale? locale, PluralResolver? cardinalResolver, PluralResolver? ordinalResolver}) => instance.setPluralResolver( + language: language, + locale: locale, + cardinalResolver: cardinalResolver, + ordinalResolver: ordinalResolver, + ); + + // synchronous versions + static AppLocale setLocaleSync(AppLocale locale, {bool? listenToDeviceLocale = false}) => instance.setLocaleSync(locale, listenToDeviceLocale: listenToDeviceLocale); + static AppLocale setLocaleRawSync(String rawLocale, {bool? listenToDeviceLocale = false}) => instance.setLocaleRawSync(rawLocale, listenToDeviceLocale: listenToDeviceLocale); + static AppLocale useDeviceLocaleSync() => instance.useDeviceLocaleSync(); + static void setPluralResolverSync({String? language, AppLocale? locale, PluralResolver? cardinalResolver, PluralResolver? ordinalResolver}) => instance.setPluralResolverSync( language: language, locale: locale, cardinalResolver: cardinalResolver, @@ -107,7 +211,10 @@ class LocaleSettings extends BaseFlutterLocaleSettings /// Provides utility functions without any side effects. class AppLocaleUtils extends BaseAppLocaleUtils { - AppLocaleUtils._() : super(baseLocale: _baseLocale, locales: AppLocale.values); + AppLocaleUtils._() : super( + baseLocale: AppLocale.en, + locales: AppLocale.values, + ); static final instance = AppLocaleUtils._(); @@ -118,6304 +225,3 @@ class AppLocaleUtils extends BaseAppLocaleUtils { static List get supportedLocales => instance.supportedLocales; static List get supportedLocalesRaw => instance.supportedLocalesRaw; } - -// translations - -// Path: -class Translations implements BaseTranslations { - /// Returns the current translations of the given [context]. - /// - /// Usage: - /// final t = Translations.of(context); - static Translations of(BuildContext context) => InheritedLocaleData.of(context).translations; - - /// You can call this constructor and build your own translation instance of this locale. - /// Constructing via the enum [AppLocale.build] is preferred. - Translations.build({Map? overrides, PluralResolver? cardinalResolver, PluralResolver? ordinalResolver}) - : assert(overrides == null, 'Set "translation_overrides: true" in order to enable this feature.'), - $meta = TranslationMetadata( - locale: AppLocale.en, - overrides: overrides ?? {}, - cardinalResolver: cardinalResolver, - ordinalResolver: ordinalResolver, - ) { - $meta.setFlatMapFunction(_flatMapFunction); - } - - /// Metadata for the translations of . - @override final TranslationMetadata $meta; - - /// Access flat map - dynamic operator[](String key) => $meta.getTranslation(key); - - late final Translations _root = this; // ignore: unused_field - - // Translations - late final _StringsAboutScreenEn AboutScreen = _StringsAboutScreenEn._(_root); - late final _StringsAddProfileByImportFromFileScreenEn AddProfileByImportFromFileScreen = _StringsAddProfileByImportFromFileScreenEn._(_root); - late final _StringsAddProfileByLinkOrContentScreenEn AddProfileByLinkOrContentScreen = _StringsAddProfileByLinkOrContentScreenEn._(_root); - late final _StringsAddProfileByScanQrcodeScanScreenEn AddProfileByScanQrcodeScanScreen = _StringsAddProfileByScanQrcodeScanScreenEn._(_root); - late final _StringsBackupAndSyncLanSyncScreenEn BackupAndSyncLanSyncScreen = _StringsBackupAndSyncLanSyncScreenEn._(_root); - late final _StringsBackupAndSyncWebdavScreenEn BackupAndSyncWebdavScreen = _StringsBackupAndSyncWebdavScreenEn._(_root); - late final _StringsDiversionGroupCustomEditScreenEn DiversionGroupCustomEditScreen = _StringsDiversionGroupCustomEditScreenEn._(_root); - late final _StringsDiversionRuleDetectScreenEn DiversionRuleDetectScreen = _StringsDiversionRuleDetectScreenEn._(_root); - late final _StringsDiversionRulesScreenEn DiversionRulesScreen = _StringsDiversionRulesScreenEn._(_root); - late final _StringsDnsSettingsScreenEn DnsSettingsScreen = _StringsDnsSettingsScreenEn._(_root); - late final _StringsFeedbackScreenEn FeedbackScreen = _StringsFeedbackScreenEn._(_root); - late final _StringsFileContentViewerScreenEn FileContentViewerScreen = _StringsFileContentViewerScreenEn._(_root); - late final _StringsHomeScreenEn HomeScreen = _StringsHomeScreenEn._(_root); - late final _StringsLaunchFailedScreenEn LaunchFailedScreen = _StringsLaunchFailedScreenEn._(_root); - late final _StringsMyProfilesEditScreenEn MyProfilesEditScreen = _StringsMyProfilesEditScreenEn._(_root); - late final _StringsMyProfilesMergeScreenEn MyProfilesMergeScreen = _StringsMyProfilesMergeScreenEn._(_root); - late final _StringsMyProfilesScreenEn MyProfilesScreen = _StringsMyProfilesScreenEn._(_root); - late final _StringsNetCheckScreenEn NetCheckScreen = _StringsNetCheckScreenEn._(_root); - late final _StringsNetConnectionsFilterScreenEn NetConnectionsFilterScreen = _StringsNetConnectionsFilterScreenEn._(_root); - late final _StringsNetConnectionsScreenEn NetConnectionsScreen = _StringsNetConnectionsScreenEn._(_root); - late final _StringsPerAppAndroidScreenEn PerAppAndroidScreen = _StringsPerAppAndroidScreenEn._(_root); - late final _StringsQrcodeScreenEn QrcodeScreen = _StringsQrcodeScreenEn._(_root); - late final _StringsRegionSettingsScreenEn RegionSettingsScreen = _StringsRegionSettingsScreenEn._(_root); - late final _StringsServerSelectScreenEn ServerSelectScreen = _StringsServerSelectScreenEn._(_root); - late final _StringsSettingsScreenEn SettingsScreen = _StringsSettingsScreenEn._(_root); - late final _StringsSpeedTestSettingsScreenEn SpeedTestSettingsScreen = _StringsSpeedTestSettingsScreenEn._(_root); - late final _StringsTextToQrCodeScreenEn TextToQrCodeScreen = _StringsTextToQrCodeScreenEn._(_root); - late final _StringsUrlTestSettingsScreenEn UrlTestSettingsScreen = _StringsUrlTestSettingsScreenEn._(_root); - late final _StringsUserAgreementScreenEn UserAgreementScreen = _StringsUserAgreementScreenEn._(_root); - late final _StringsVersionUpdateScreenEn VersionUpdateScreen = _StringsVersionUpdateScreenEn._(_root); - late final _StringsCommonWidgetEn CommonWidget = _StringsCommonWidgetEn._(_root); - late final _StringsServerManagerEn ServerManager = _StringsServerManagerEn._(_root); - late final _StringsMainEn main = _StringsMainEn._(_root); - String get enable => 'Enable'; - String get disable => 'Disable'; - String get prefer => 'Prefer'; - String get only => 'Only'; - String get open => 'Open'; - String get close => 'Close'; - String get quit => 'Quit'; - String get add => 'Add'; - String get remove => 'Remove'; - String get edit => 'Edit'; - String get view => 'View'; - String get more => 'More'; - String get addProfile => 'Add Profile'; - String get addSuccess => 'Added successfully'; - String addSuccessThen({required Object p}) => 'Profile generated successfully, please go to [${p}] to view'; - String addFailed({required Object p}) => 'Add failed:${p}'; - String get removeConfirm => 'Are you sure to delete?'; - String get tips => 'Info'; - String get copy => 'Copy'; - String get ok => 'Ok'; - String get cancel => 'Cancel'; - String get feedback => 'Feedback'; - String get faq => 'FAQ'; - String get download => 'Download'; - String get loading => 'Loading...'; - String updateFailed({required Object p}) => 'Update failed:${p}'; - String get days => 'Days'; - String get hours => 'Hours'; - String get minutes => 'Minutes'; - String get seconds => 'Seconds'; - String get protocol => 'Protocol'; - String get search => 'Search'; - String get custom => 'Custom'; - String get connect => 'Connect'; - String get disconnect => 'Disconnect'; - String get connected => 'Connected'; - String get disconnected => 'Disconnected'; - String get connecting => 'Connecting'; - String get connectTimeout => 'Connect Timeout'; - String get timeout => 'Timeout'; - String get language => 'Language'; - String get next => 'Next'; - String get done => 'Done'; - String get apply => 'Apply'; - String get refresh => 'Refresh'; - String get retry => 'Retry?'; - String get none => 'None'; - String get reset => 'Reset'; - String get submit => 'Submit'; - String get account => 'Account'; - String get password => 'Password'; - String get required => 'Required'; - String get diversion => 'Diversion'; - String get diversionRules => 'Diversion Rules'; - String get diversionRulesEnable => 'Enable [ISP] Diversion Rules'; - String get diversionCustomGroup => 'Custom Diversion Group'; - String get diversionCustomGroupPreset => 'Preset [Custom Diversion Group]'; - String get diversionCustomGroupPresetTips => 'Note: Enabled items will be added/overwritten to [Custom Diversion Group] and [Diversion Rules]'; - String get diversionCustomGroupAddTips => 'Note: After adding, you may need to manually adjust the order, otherwise the newly added diversion may not take effect'; - String get urlTestCustomGroup => 'Custom Proxy Group'; - String get rulesetEnableTips => 'Tip: After turning on the options, please go to[Diversion Rules]to set the relevant rules, otherwise they will not take effect'; - String get ispUserAgentTips => '[ISP] will send data of different subscription types based on [UserAgent] in [HTTP] request'; - String get ispDiversionTips => '[ISP] provides traffic diversion rules; [V2Ray] type subscriptions do not support traffic diversion rules'; - String get staticIP => 'Static IP'; - String get other => 'Other'; - String get dns => 'DNS'; - String get url => 'URL'; - String get isp => 'ISP'; - String get tls => 'TLS'; - String get userAgent => 'UserAgent'; - String get urlInvalid => 'Invalid URL'; - String get outboundActionCurrentSelected => 'Current Selected'; - String get outboundActionUrltest => 'Auto Select'; - String get outboundActionDirect => 'Direct'; - String get outboundActionBlock => 'Block'; - String get routeFinal => 'final'; - String get rulesetGeoSite => 'GeoSite'; - String get rulesetGeoIp => 'GeoIP'; - String get rulesetAcl => 'ACL'; - String get iCloud => 'iCloud'; - String get appleTV => 'Apple TV'; - String get webdav => 'Webdav'; - String get setting => 'Settings'; - String get protocolSniff => 'Protocol Sniff'; - String get protocolSniffOverrideDestination => 'The Sniff domain name override the connection target address'; - String get remark => 'Remark'; - String get remarkCannotEmpty => 'Remarks can not be empty'; - String get remarkTooLong => 'Remarks up to 32 characters'; - String get remarkExist => 'Remark already exists, please use another name'; - String get domainSuffix => 'Domain Suffix'; - String get domain => 'Domain'; - String get domainKeyword => 'Domain Keyword'; - String get domainRegex => 'Domain Regex'; - String get ip => 'IP'; - String get port => 'Port'; - String get appPackage => 'App Package Name'; - String get processName => 'Process Name'; - String get processPath => 'Process Path'; - String get systemProxy => 'System Proxy'; - String get netInterfaces => 'Net Interfaces'; - String get netSpeed => 'Speed'; - String get website => 'Website'; - String get rule => 'Rule'; - String get global => 'Global'; - String get qrcode => 'QR Code'; - String get scanQrcode => 'Scan QR Code'; - String get scanResult => 'Scan Result'; - String get backupAndSync => 'Backup and Sync'; - String get importAndExport => 'Import and Export'; - String get import => 'Import'; - String get export => 'Export'; - String get termOfUse => 'Terms of Service'; - String get privacyPolicy => 'Privacy & Policy'; - String get about => 'About'; - String get name => 'Name'; - String get version => 'Version'; - String get notice => 'Notice'; - String get sort => 'Reorder'; - String get novice => 'Novice Mode'; - String get recommended => 'Recommend'; - String innerError({required Object p}) => 'Inner Error:${p}'; - String get logicOperation => 'Logic Operation'; - String get share => 'Share'; - String get candidateWord => 'Candidate Words'; - String get keywordsOrRegx => 'Keywords/Regular'; - String get importFromClipboard => 'Import From Clipboard'; - String get exportToClipboard => 'Export to Clipboard'; - String get server => 'Server'; - String get appleTVConnectTurnOfprivateDirect => 'Please turn on [Private network direct connection] first'; - String targetConnectFailed({required Object p}) => 'Failed to connect to [${p}]. Please make sure the devices are in the same LAN and enable [Private Network Direct Connection]'; - String get appleTVSync => 'Synchronize the current core configuration to Apple TV - Karing'; - String get appleTVSyncDone => 'Synchronization is complete. Please go to Apple TV - Karing to start the connection/restart the connection'; - String get appleTVRemoveCoreConfig => 'Delete Apple TV - Karing Core Configuration'; - String get appleTVRemoveCoreConfigDone => 'Apple TV - Karing\'s Core Configuration deleted; VPN service disconnected'; - String get appleTVUrlInvalid => 'Invalid URL, please open Apple TV - Karing and scan the QR code displayed by Karing'; - String get remoteProfileEditConfirm => 'After the Profile is updated, the node changes will be restored. Continue?'; - String invalidFileType({required Object p}) => 'Invalid file type:${p}'; - Map get locales => { - 'en': 'English', - 'zh-CN': '简体中文', - 'ar': 'عربي', - 'ru': 'Русский', - 'fa': 'فارسی', - }; -} - -// Path: AboutScreen -class _StringsAboutScreenEn { - _StringsAboutScreenEn._(this._root); - - final Translations _root; // ignore: unused_field - - // Translations - String get installRefer => 'Install Refer'; - String get versionChannel => 'Auto Update Channel'; - String get disableUAReport => 'Turn Off Action Data Report'; - String get disableUAReportTip => 'Behavioral data reporting helps us improve the product experience; versions lower than the main version will automatically turn off all data reporting (except [App Activation])'; - String get devOptions => 'Developer Options'; - String get enableDebugLog => 'Enable Debug Log'; - String get viewFilsContent => 'View Files'; - String get enablePprof => 'Enable pprof'; - String get pprofPanel => 'pprof Panel'; - String get openDir => 'Open File Directory'; - String get useOriginalSBProfile => 'Use original sing-box Profile'; -} - -// Path: AddProfileByImportFromFileScreen -class _StringsAddProfileByImportFromFileScreenEn { - _StringsAddProfileByImportFromFileScreenEn._(this._root); - - final Translations _root; // ignore: unused_field - - // Translations - String get title => 'Import Profile File'; - String get chooseFile => 'Select File'; - String get configExist => 'The Profile already exists, please do not add it repeatedly'; -} - -// Path: AddProfileByLinkOrContentScreen -class _StringsAddProfileByLinkOrContentScreenEn { - _StringsAddProfileByLinkOrContentScreenEn._(this._root); - - final Translations _root; // ignore: unused_field - - // Translations - String get title => 'Add Profile Link'; - String get updateTimerInterval => 'Update interval'; - String get updateTimerIntervalTips => 'To disable please set to:<5m'; - String get profileLinkContent => 'Profile Link/Content'; - String get profileLinkContentHit => 'Profile Link/Content [Required] (Support Clash,V2ray(batch supported),Stash,Karing,Sing-box,Shadowsocks,Sub Profile links)'; - String get subscriptionCannotEmpty => 'Profile Link can not be empty'; - String get configExist => 'The Profile already exists, please do not add it repeatedly'; - String get invalidUrl => 'The Profile Link is too long'; - String addFailedFormatException({required Object p}) => 'The format is wrong, please correct it and add it again:${p}'; - String addFailedThenDownloadAndImport({required Object p}) => 'Add failed: ${p}, please try to modify the [UserAgent] and try again, or use the device\'s built-in browser to open the configuration link and import the configuration file downloaded by the browser into this application'; - String addFailedHandshakeException({required Object p}) => 'Add failed: ${p}, please tun on the proxy or modify the current proxy node and try again'; -} - -// Path: AddProfileByScanQrcodeScanScreen -class _StringsAddProfileByScanQrcodeScanScreenEn { - _StringsAddProfileByScanQrcodeScanScreenEn._(this._root); - - final Translations _root; // ignore: unused_field - - // Translations - String get copy => 'Copy Link'; - String get open => 'Open Link'; - String get requestCameraPermission => 'Please enable camera permission'; - String get requestScreenAccess => 'Please go to System Settings - Privacy and Security - Screen Recording to add permissions for this application'; - String get screenshot => 'Screenshot'; - String get scanFromImage => 'Scan From Image'; - String get scanNoResult => 'Failed to parse the image, please make sure the screenshot is a valid QR code'; - String get scanEmptyResult => 'Scan Result is empty'; - String scanException({required Object p}) => 'Failed to parse the image, please make sure the screenshot is a valid QR code:${p}'; -} - -// Path: BackupAndSyncLanSyncScreen -class _StringsBackupAndSyncLanSyncScreenEn { - _StringsBackupAndSyncLanSyncScreenEn._(this._root); - - final Translations _root; // ignore: unused_field - - // Translations - String get title => 'LAN Sync'; - String get lanSyncNotQuitTips => 'Do not exit this interface before synchronization is completed'; -} - -// Path: BackupAndSyncWebdavScreen -class _StringsBackupAndSyncWebdavScreenEn { - _StringsBackupAndSyncWebdavScreenEn._(this._root); - - final Translations _root; // ignore: unused_field - - // Translations - String get webdavServerUrl => 'Server Url'; - String get webdavRequired => 'Can not be empty'; - String get webdavLoginFailed => 'Login failed:'; - String get webdavListFailed => 'Failed to get file list:'; -} - -// Path: DiversionGroupCustomEditScreen -class _StringsDiversionGroupCustomEditScreenEn { - _StringsDiversionGroupCustomEditScreenEn._(this._root); - - final Translations _root; // ignore: unused_field - - // Translations - String invalidDomain({required Object p}) => 'Invalid [Domain]:${p}'; - String invalidIpCidr({required Object p}) => 'Invalid [IP Cidr]:${p}'; - String invalidPort({required Object p}) => 'Invalid [Port]:${p}'; - String invalidRuleSet({required Object p}) => 'Invalid [Rule Set]:${p}, The URL must be a valid https URL and a binary file with the file extension .srs/.json'; - String invalidRuleSetBuildIn({required Object p}) => 'Invalid [Rule Set(build-in)]:${p}, The format is geosite:xxx or geoip:xxx or acl:xxx, and xxx should be a valid rule name'; - String get setDiversionRule => 'Tip: After saving, please go to [Diversion Rules] to set relevant rules, otherwise they will not take effect'; -} - -// Path: DiversionRuleDetectScreen -class _StringsDiversionRuleDetectScreenEn { - _StringsDiversionRuleDetectScreenEn._(this._root); - - final Translations _root; // ignore: unused_field - - // Translations - String get title => 'Diversion Rule Detect'; - String get detect => 'Detect'; - String get rule => 'Rule:'; - String get outbound => 'Proxy Server:'; -} - -// Path: DiversionRulesScreen -class _StringsDiversionRulesScreenEn { - _StringsDiversionRulesScreenEn._(this._root); - - final Translations _root; // ignore: unused_field - - // Translations - String get diversionRulesMatchTips => 'Tip: Try to match the rules from top to bottom. If no rule is matched, use [final]'; -} - -// Path: DnsSettingsScreen -class _StringsDnsSettingsScreenEn { - _StringsDnsSettingsScreenEn._(this._root); - - final Translations _root; // ignore: unused_field - - // Translations - String get ispCanNotEmpty => 'ISP can not be empty'; - String get urlCanNotEmpty => 'URL can not be empty'; - String error({required Object p}) => 'Unsupported type:${p}'; - String get dnsDesc => 'The first column of delay data is the direct connection query delay;\nThe second column: Turn on [[Proxy Traffic]Resolve DNS through proxy server]: the delay data is the query delay forwarded through the current proxy server; if the [[Proxy Traffic]Resolve DNS through proxy server]: The delay data is the direct connection query delay'; -} - -// Path: FeedbackScreen -class _StringsFeedbackScreenEn { - _StringsFeedbackScreenEn._(this._root); - - final Translations _root; // ignore: unused_field - - // Translations - String get content => 'Feedback Content'; - String get contentHit => 'Required, up to 500 characters'; - String get contentCannotEmpty => 'Feedback content can not be empty'; -} - -// Path: FileContentViewerScreen -class _StringsFileContentViewerScreenEn { - _StringsFileContentViewerScreenEn._(this._root); - - final Translations _root; // ignore: unused_field - - // Translations - String get title => 'File Content Viewer'; - String get chooseFile => 'Select File'; - String get clearFileContent => 'Are you sure to clear the content of the file?'; - String get clearFileContentTips => 'Are you sure to clear the content of the Profile file? Clearing the Profile file may cause data loss or abnormal application functions, please operate with caution'; -} - -// Path: HomeScreen -class _StringsHomeScreenEn { - _StringsHomeScreenEn._(this._root); - - final Translations _root; // ignore: unused_field - - // Translations - String get toSelectServer => 'Please Select a Server'; - String get invalidServer => 'is invalid, please choose again'; - String get disabledServer => 'is disabled, please choose again'; - String get expiredServer => 'No servers available, profiles may be expired or disabled'; - String systemProxyTips({required Object sp, required Object hp}) => 'socks:${sp},http(s):${hp}'; - String get trafficTotal => 'Traffic Total'; - String get trafficProxy => 'Traffic Proxy'; - String get myLinkEmpty => 'Please set up [Shortcut Link] before using it'; - String get deviceNoSpace => 'Not enough disk space'; - String tooMuchServers({required Object p, required Object p1}) => 'Too many proxy servers [${p}>${p1}], and the connection may fail due to system memory limitations'; -} - -// Path: LaunchFailedScreen -class _StringsLaunchFailedScreenEn { - _StringsLaunchFailedScreenEn._(this._root); - - final Translations _root; // ignore: unused_field - - // Translations - String get invalidProcess => 'The app failed to start [Invalid process name], please reinstall the app to a separate directory'; - String get invalidProfile => 'The app failed to start [Failed to access the profile], please reinstall the app'; - String get invalidVersion => 'The app failed to start [Invalid version], please reinstall the app'; - String get systemVersionLow => 'The app failed to start [system version too low]'; - String get startFromUNC => 'The installation path is invalid, please reinstall it to a valid path'; -} - -// Path: MyProfilesEditScreen -class _StringsMyProfilesEditScreenEn { - _StringsMyProfilesEditScreenEn._(this._root); - - final Translations _root; // ignore: unused_field - - // Translations - String get title => 'Profile Edit'; - String get urlExist => 'URL already exists, please use another URL'; - String get updateTimerInterval => 'Update interval'; - String get updateTimerIntervalTips => 'To disable please set to:<5m'; - String get reloadAfterProfileUpdate => 'Reload after Profile update'; - String get testLatencyAfterProfileUpdate => 'Start latency tests after Profile Automatically update'; - String get testLatencyAfterProfileUpdateTips => 'VPN needs to be connected, and [Reload after Profile update] Enabled'; - String get testLatencyAutoRemove => 'Automatically remove servers that fail latency tests'; - String get testLatencyAutoRemoveTips => 'Try up to 3 times'; -} - -// Path: MyProfilesMergeScreen -class _StringsMyProfilesMergeScreenEn { - _StringsMyProfilesMergeScreenEn._(this._root); - - final Translations _root; // ignore: unused_field - - // Translations - String get profilesMerge => 'Profiles Merge'; - String get profilesMergeTarget => 'Target Profile'; - String get profilesMergeSource => 'Source Profiles'; - String get profilesMergeTips => 'Tip: Diversion of the source profiles will be discarded'; -} - -// Path: MyProfilesScreen -class _StringsMyProfilesScreenEn { - _StringsMyProfilesScreenEn._(this._root); - - final Translations _root; // ignore: unused_field - - // Translations - String get title => 'Profiles'; - String get atLeastOneEnable => 'Cannot be disabled, please keep at least one profile enable'; -} - -// Path: NetCheckScreen -class _StringsNetCheckScreenEn { - _StringsNetCheckScreenEn._(this._root); - - final Translations _root; // ignore: unused_field - - // Translations - String get title => 'Net Check'; - String get warn => 'Note: Due to the influence of network environment and diversion rules, the test results are not completely equivalent to the actual results.'; - String get check => 'Check'; - String get invalidDomain => 'Invalid Domain Name'; - String get connectivity => 'Network Connectivity'; - String connectivityTestIpv4AllFailed({required Object p}) => 'Ipv4 Connection test [${p}] all failed'; - String get connectivityTestIpv4Ok => 'Ipv4 connection succeeded'; - String connectivityTestIpv6AllFailed({required Object p}) => 'Ipv6 Connection test [${p}] all failed, Your network may not support ipv6'; - String get connectivityTestIpv6Ok => 'Ipv6 connection succeeded'; - String get connectivityTestOk => 'The network is connected to the Internet'; - String get connectivityTestFailed => 'The network is not yet connected to the Internet'; - String get remoteRulesetsDownloadOk => 'All downloaded successfully'; - String get remoteRulesetsDownloadNotOk => 'Downloading or download failed'; - String get outbound => 'Proxy Server'; - String outboundOk({required Object p}) => '[${p}] connection succeeded'; - String outboundFailed({required Object p1, required Object p2}) => '[${p1}] connection failed\nError:[${p2}]'; - String get dnsServer => 'DNS Server'; - String dnsOk({required Object p1, required Object p2, required Object p3, required Object p4}) => '[${p1}]DNS query succeeded\nDNS Rule:[${p2}]\nLatency:[${p3} ms]\nAddress:[${p4}]'; - String dnsFailed({required Object p1, required Object p2, required Object p3}) => '[${p1}]DNS query succeeded\n nDNS Rule:[${p2}]\nError:[${p3}]'; - String get host => 'HTTP Connection'; - String hostConnection({required Object p1, required Object p2, required Object p3}) => '[${p1}]\nDiversionRule:[${p2}]\nProxy Server:[${p3}]'; - String get hostConnectionOk => 'connection succeeded'; - String hostConnectionFailed({required Object p}) => 'connection failed:[${p}]'; -} - -// Path: NetConnectionsFilterScreen -class _StringsNetConnectionsFilterScreenEn { - _StringsNetConnectionsFilterScreenEn._(this._root); - - final Translations _root; // ignore: unused_field - - // Translations - String get title => 'Connections Filter'; - String get hostIp => 'Domain/IP'; - String get app => 'App'; - String get rule => 'Rule'; - String get chain => 'Outbound'; -} - -// Path: NetConnectionsScreen -class _StringsNetConnectionsScreenEn { - _StringsNetConnectionsScreenEn._(this._root); - - final Translations _root; // ignore: unused_field - - // Translations - String get title => 'Connections'; - String get copyAsCSV => 'Copied to CSV format'; - String get selectType => 'Select Diversion Type'; -} - -// Path: PerAppAndroidScreen -class _StringsPerAppAndroidScreenEn { - _StringsPerAppAndroidScreenEn._(this._root); - - final Translations _root; // ignore: unused_field - - // Translations - String get title => 'Per-App Proxy'; - String get whiteListMode => 'Whitelist Mode'; - String get whiteListModeTip => 'When enabled: only the apps that have been checked are proxies; when not enabled: only the apps that are not checked are proxies'; - String get hideSystemApp => 'Hide System Apps'; - String get hideAppIcon => 'Hide App Icons'; - String get enableAppQueryPermission => 'Turn on [App list query] Permission'; -} - -// Path: QrcodeScreen -class _StringsQrcodeScreenEn { - _StringsQrcodeScreenEn._(this._root); - - final Translations _root; // ignore: unused_field - - // Translations - String get tooLong => 'The text is too long to display'; - String get copy => 'Copy Link'; - String get open => 'Open Link'; - String get share => 'Share Link'; - String get shareImage => 'Share QR Code'; -} - -// Path: RegionSettingsScreen -class _StringsRegionSettingsScreenEn { - _StringsRegionSettingsScreenEn._(this._root); - - final Translations _root; // ignore: unused_field - - // Translations - String get title => 'Country Or Region'; - String get Regions => 'Tip: Please set your current country or region correctly, otherwise it may cause network diversion problems'; -} - -// Path: ServerSelectScreen -class _StringsServerSelectScreenEn { - _StringsServerSelectScreenEn._(this._root); - - final Translations _root; // ignore: unused_field - - // Translations - String get title => 'Select Server'; - String get autoSelectServer => 'Auto select the server with the lowest latency'; - String get recentUse => 'Recently Used'; - String get myFav => 'My Favs'; - String selectLocal({required Object p}) => 'The selected server is a local address and may not work properly:${p}'; - String get selectRequireEnableIPv6 => 'The selected server is an IPv6 address and requires [Enable IPv6]'; - String get selectDisabled => 'This server has been disabled'; - String get error404 => 'Latency detection encountered an error, please check if there is a configuration with the same content'; -} - -// Path: SettingsScreen -class _StringsSettingsScreenEn { - _StringsSettingsScreenEn._(this._root); - - final Translations _root; // ignore: unused_field - - // Translations - String ispFaq({required Object p}) => 'FAQ[${p}]'; - String cleanISP({required Object p}) => 'Clear ISP[${p}]'; - String get openISP => 'Open ISP link'; - String get cleanISPNoParam => 'Clear ISP Info'; - String get getTranffic => 'Get Traffic'; - String get tutorial => 'Tutorial'; - String get commonlyUsedRulesets => 'Commonly Used Rulesets'; - String get howToRemoveAds => 'How to remove ads'; - String get htmlBoard => 'Online Panel'; - String get dnsLeakDetection => 'DNS Leaks Detection'; - String get speedTest => 'Speed Test'; - String get downloadProfilePreferProxy => 'Prefer Proxy to Download Profile'; - String get downloadProfilePreferProxyTips => 'If currently connected, the profile will be downloaded through the connected proxy first'; - String get rulesetDirectDownlad => 'Rule Set Direct Download'; - String get hideUnusedDiversionGroup => 'Hide Unused Diversion Groups'; - String get disableISPDiversionGroup => 'Disable ISP Diversion Rules'; - String get portSetting => 'Port'; - String get portSettingRule => 'Rule Based'; - String get portSettingDirectAll => 'Direct All'; - String get portSettingProxyAll => 'Proxy All'; - String get portSettingControl => 'Control and Sync'; - String get portSettingCluster => 'Cluster Service'; - String get modifyPort => 'Modify Port'; - String get ipStrategyTips => 'Before enabling, please confirm that your network supports IPv6, otherwise some traffic cannot be accessed normally.'; - String get tunAppendHttpProxy => 'Append HTTP Proxy to VPN'; - String get tunAppendHttpProxyTips => 'Some apps will bypass virtual NIC Device and directly connect to HTTP proxy'; - String get tlsInsecureEnable => 'Skip Certificate Verification'; - String get tlsFragmentEnable => 'Enable TLS Fragment'; - String get tlsFragmentSize => 'TLS Fragment Size'; - String get tlsFragmentSleep => 'TLS Fragment Sleep'; - String get tlsMixedCaseSNIEnable => 'Enable TLS Mixed SNI'; - String get tlsPaddingEnable => 'Enable TLS Padding'; - String get tlsPaddingSize => 'TLS Padding Size'; - String get dnsEnableRule => 'Enable DNS Diversion rules'; - String get dnsEnableFakeIp => 'Enable FakeIP'; - String get dnsEnableClientSubnet => 'Enable ECS'; - String get dnsEnableProxyResolveByProxy => '[Proxy Traffic]Resolve DNS through proxy server'; - String get dnsEnableFinalResolveByProxy => '[final]Resolve DNS through proxy server'; - String get dnsTestDomain => 'Test Domain'; - String get dnsTestDomainInvalid => 'Invalid Domain'; - String get dnsTypeOutbound => 'Proxy Server'; - String get dnsTypeDirect => 'Direct Traffic'; - String get dnsTypeProxy => 'Proxy Traffic'; - String get dnsTypeResolver => 'DNS Server'; - String get dnsEnableRuleTips => 'After enabling, the domain name will select the corresponding DNS server for resolution according to the diversion rules'; - String get dnsEnableFakeIpTips => 'After enabling FakeIP, if you disconnect from VPN, your app may need to be restarted; this feature requires [TUN mode] to be enabled'; - String get dnsTypeOutboundTips => 'Domain name resolution for Proxy Server'; - String get dnsTypeDirectTips => 'Domain name resolution for Direct Traffic'; - String get dnsTypeProxyTips => 'Domain name resolution for Proxy Traffic'; - String get dnsTypeResolverTips => 'Domain name resolution for Other DNS Server'; - String get dnsTypeFinalTips => 'Domain name resolution for Other Traffic'; - String get dnsAutoSetServer => 'Auto Setup Server'; - String get dnsResetServer => 'Reset Server'; - String get inboundDomainResolve => 'Resolve Inbound Domain names'; - String get privateDirect => 'Private Network Direct connection'; - String inboundDomainResolveTips({required Object p}) => 'Some domain names that are not configured with diversion rules need to be resolved before they can hit the IP-based diversion rules; this feature affects inbound requests to the proxy port [${p}]'; - String get useRomoteRes => 'Use Remote Resources'; - String get autoSelect => 'Auto Select'; - String get autoSelectServerIgnorePerProxyServer => 'Ignore [Per-Proxy] proxy server'; - String get autoSelectServerInterval => 'Latency Checks Interval'; - String get autoSelectServerReTestIfNetworkUpdate => 'Re-check Latency when Network Changes'; - String get autoSelectServerUpdateCurrentServerAfterManualUrltest => 'Update the Current Server after Manual Latency Check'; - String get autoSelectServerIntervalTips => 'The shorter the time interval, the more timely the server latency data updates, which will occupy more resources and consume more power'; - String get autoSelectServerFavFirst => 'Pri-Use [My Favs]'; - String get autoSelectServerFavFirstTips => 'If the [My Favs] list is not empty, Then use the servers in [My Favs]'; - String get autoSelectServerFilter => 'Filter Invalid Servers'; - String autoSelectServerFilterTips({required Object p}) => 'Server latency checks that fail will be filtered out; if no server is available after filtering, the first [${p}] servers will be used instead'; - String get autoSelectServerLimitedNum => 'Maximum number of servers'; - String get autoSelectServerLimitedNumTips => 'Servers exceeding this number will be filtered out'; - String get numInvalid => 'Invalid number'; - String get hideInvalidServer => 'Hide Invalid Servers'; - String get sortServer => 'Servers Sorting'; - String get sortServerTips => 'Sort by latency from low to high'; - String get selectServerHideRecommand => 'Hide [Recommend]'; - String get selectServerHideRecent => 'Hide [Recently Used]'; - String get selectServerHideFav => 'Hide [My Favs]'; - String get homeScreen => 'Home Screen'; - String get theme => 'Theme'; - String get myLink => 'Shortcut Link'; - String get myLinkInvalid => 'Invalid URL'; - String get autoConnectAfterLaunch => 'Auto Connection after Launch'; - String get hideAfterLaunch => 'Hide window after startup'; - String get autoSetSystemProxy => 'Auto Set System Proxy when Connected'; - String get disconnectWhenQuit => 'Disconnect when App Exits'; - String get allowBypass => 'Allow Apps to Bypass VPN'; - String get lanSyncTo => 'Sync to others'; - String get lanSyncFrom => 'Sync from others'; - String get lanSyncScanQRcode => 'Scan QR code to Sync'; - String get syncToConfirm => 'Confirm sync to the other party?'; - String get syncDone => 'Sync completed'; - String get importSuccess => 'Import Success'; - String get rewriteConfirm => 'This file will overwrite the existing local configuration. Do you want to continue?'; - String get networkShare => 'Network Sharing'; - String get frontProxy => 'Per-Proxy'; - String get frontProxyTips => 'Data->Per-Proxy server->Proxy server->Target server'; - String get allowOtherHostsConnect => 'Allow Others to Connect'; - String allowOtherHostsConnectTips({required Object sp, required Object hp}) => 'socks:${sp},http(s):${hp}'; - String get tunAutoRoute => 'Auto Route'; - String get tunStrictRoute => 'Strict Route'; - String get tunStrictRouteTips => 'If after turning on sharing, others cannot access this device, please try turning off this switch'; - String get enableCluster => 'Enable Socks/Http Proxy Cluster'; - String get clusterAllowOtherHostsConnect => 'Allow Others to Connect to Cluster'; - String clusterAllowOtherHostsConnectTips({required Object hp}) => 'http://127.0.0.1:${hp}/get_proxies'; - String get clusterAuth => 'Proxy Cluster Authentication'; - String get clusterConfirm => 'Please confirm that the servers latency have been checked, and proxy services will not be created if they are not checked or checked incorrectly'; - String get tunMode => 'TUN Mode'; - String get tunModeTips => 'The TUN mode will take over all the traffic of the system [In this mode, you can leave the system proxy unenabled]'; - String get tunModeRunAsAdmin => 'The TUN mode requires system administrator permissions, please restart the app as an administrator'; - String get tunStack => 'Stack'; - String get launchAtStartup => 'Launch at Startup'; - String get quitWhenSwitchSystemUser => 'Exit App when Switch System Users'; - String get handleScheme => 'System Scheme Call'; - String get portableMode => 'Portable Mode'; - String get portableModeDisableTips => 'If you need to exit portable mode, please exit [karing] and manually delete the [profiles] folder in the same directory as [karing.exe]'; - String get handleKaringScheme => 'Handle karing:// Call'; - String get handleClashScheme => 'Handle clash:// Call'; - String get handleSingboxScheme => 'Handle sing-box:// Call'; - String get removeSystemVPNConfig => 'Delete system VPN configuration'; - String get timeConnectOrDisconnect => 'Scheduled connect/disconnect'; - String get timeConnectOrDisconnectTips => 'VPN must be connected to take effect; after it is turned on, [Automatic Sleep] will be disabled'; - String timeConnectAndDisconnectInterval({required Object p}) => 'The connection/disconnection interval cannot be less than ${p} minutes'; - String get disableFontScaler => 'Disable Font scaling(Restart takes effect)'; - String get autoOrientation => 'Rotate with the screen'; - String get restartTakesEffect => 'Restart takes effect'; - String get resetSettings => 'Reset Settings'; - String get cleanCache => 'Cleanup Cache'; - String get cleanCacheDone => 'Cleanup completed'; - String get appleTestFlight => 'Apple TestFlight'; - String get appleAppStore => 'Apple AppStore'; - String hasNewVersion({required Object p}) => 'Update Version ${p}'; - String get follow => 'Follow Us'; - String get contactUs => 'Contact Us'; - String get rateInApp => 'Rate Us'; - String get rateInAppStore => 'Rate Us in AppStore'; -} - -// Path: SpeedTestSettingsScreen -class _StringsSpeedTestSettingsScreenEn { - _StringsSpeedTestSettingsScreenEn._(this._root); - - final Translations _root; // ignore: unused_field - - // Translations - String get title => 'Speed Test URL'; - String get error => 'Must be Valid https URL'; -} - -// Path: TextToQrCodeScreen -class _StringsTextToQrCodeScreenEn { - _StringsTextToQrCodeScreenEn._(this._root); - - final Translations _root; // ignore: unused_field - - // Translations - String get title => 'Text To QR Code'; - String get convert => 'Convert'; -} - -// Path: UrlTestSettingsScreen -class _StringsUrlTestSettingsScreenEn { - _StringsUrlTestSettingsScreenEn._(this._root); - - final Translations _root; // ignore: unused_field - - // Translations - String get title => 'Latency Checks URL'; - String get error => 'Must be Valid https URL'; -} - -// Path: UserAgreementScreen -class _StringsUserAgreementScreenEn { - _StringsUserAgreementScreenEn._(this._root); - - final Translations _root; // ignore: unused_field - - // Translations - String get privacyFirst => 'Your Privacy Comes First'; - String get agreeAndContinue => 'Accept & Continue'; -} - -// Path: VersionUpdateScreen -class _StringsVersionUpdateScreenEn { - _StringsVersionUpdateScreenEn._(this._root); - - final Translations _root; // ignore: unused_field - - // Translations - String versionReady({required Object p}) => 'The new version[${p}] is ready'; - String get update => 'Restart To Update'; - String get cancel => 'Not Now'; -} - -// Path: CommonWidget -class _StringsCommonWidgetEn { - _StringsCommonWidgetEn._(this._root); - - final Translations _root; // ignore: unused_field - - // Translations - String get diableAlwayOnVPN => 'If [Always on VPN] is turned on, please turn off [Always on VPN] and try connecting again'; - String get resetPort => 'Please change the port to another available port or close the application occupying the port.'; -} - -// Path: ServerManager -class _StringsServerManagerEn { - _StringsServerManagerEn._(this._root); - - final Translations _root; // ignore: unused_field - - // Translations - String get noServerAvaliable => 'No server avaliable, Make sure the Profile Link or Profile File is valid; if your Profile comes from GitHub, please obtain the link from the [Raw] button on the page'; - String get filePathCannotEmpty => 'The file path can not be empty'; - String fileNotExist({required Object p}) => 'File does not exist:${p}'; - String get urlCannotEmpty => 'Link can not be empty'; - String get invalidUrl => 'Invalid Profile Link'; - String get parseFailed => 'Parsing Profile failed'; -} - -// Path: main -class _StringsMainEn { - _StringsMainEn._(this._root); - - final Translations _root; // ignore: unused_field - - // Translations - late final _StringsMainTrayEn tray = _StringsMainTrayEn._(_root); -} - -// Path: main.tray -class _StringsMainTrayEn { - _StringsMainTrayEn._(this._root); - - final Translations _root; // ignore: unused_field - - // Translations - String get menuOpen => ' Open '; - String get menuExit => ' Exit '; -} - -// Path: -class _StringsAr implements Translations { - /// You can call this constructor and build your own translation instance of this locale. - /// Constructing via the enum [AppLocale.build] is preferred. - _StringsAr.build({Map? overrides, PluralResolver? cardinalResolver, PluralResolver? ordinalResolver}) - : assert(overrides == null, 'Set "translation_overrides: true" in order to enable this feature.'), - $meta = TranslationMetadata( - locale: AppLocale.ar, - overrides: overrides ?? {}, - cardinalResolver: cardinalResolver, - ordinalResolver: ordinalResolver, - ) { - $meta.setFlatMapFunction(_flatMapFunction); - } - - /// Metadata for the translations of . - @override final TranslationMetadata $meta; - - /// Access flat map - @override dynamic operator[](String key) => $meta.getTranslation(key); - - @override late final _StringsAr _root = this; // ignore: unused_field - - // Translations - @override late final _StringsAboutScreenAr AboutScreen = _StringsAboutScreenAr._(_root); - @override late final _StringsAddProfileByImportFromFileScreenAr AddProfileByImportFromFileScreen = _StringsAddProfileByImportFromFileScreenAr._(_root); - @override late final _StringsAddProfileByLinkOrContentScreenAr AddProfileByLinkOrContentScreen = _StringsAddProfileByLinkOrContentScreenAr._(_root); - @override late final _StringsAddProfileByScanQrcodeScanScreenAr AddProfileByScanQrcodeScanScreen = _StringsAddProfileByScanQrcodeScanScreenAr._(_root); - @override late final _StringsBackupAndSyncLanSyncScreenAr BackupAndSyncLanSyncScreen = _StringsBackupAndSyncLanSyncScreenAr._(_root); - @override late final _StringsBackupAndSyncWebdavScreenAr BackupAndSyncWebdavScreen = _StringsBackupAndSyncWebdavScreenAr._(_root); - @override late final _StringsDiversionGroupCustomEditScreenAr DiversionGroupCustomEditScreen = _StringsDiversionGroupCustomEditScreenAr._(_root); - @override late final _StringsDiversionRuleDetectScreenAr DiversionRuleDetectScreen = _StringsDiversionRuleDetectScreenAr._(_root); - @override late final _StringsDiversionRulesScreenAr DiversionRulesScreen = _StringsDiversionRulesScreenAr._(_root); - @override late final _StringsDnsSettingsScreenAr DnsSettingsScreen = _StringsDnsSettingsScreenAr._(_root); - @override late final _StringsFeedbackScreenAr FeedbackScreen = _StringsFeedbackScreenAr._(_root); - @override late final _StringsFileContentViewerScreenAr FileContentViewerScreen = _StringsFileContentViewerScreenAr._(_root); - @override late final _StringsHomeScreenAr HomeScreen = _StringsHomeScreenAr._(_root); - @override late final _StringsLaunchFailedScreenAr LaunchFailedScreen = _StringsLaunchFailedScreenAr._(_root); - @override late final _StringsMyProfilesEditScreenAr MyProfilesEditScreen = _StringsMyProfilesEditScreenAr._(_root); - @override late final _StringsMyProfilesMergeScreenAr MyProfilesMergeScreen = _StringsMyProfilesMergeScreenAr._(_root); - @override late final _StringsMyProfilesScreenAr MyProfilesScreen = _StringsMyProfilesScreenAr._(_root); - @override late final _StringsNetCheckScreenAr NetCheckScreen = _StringsNetCheckScreenAr._(_root); - @override late final _StringsNetConnectionsFilterScreenAr NetConnectionsFilterScreen = _StringsNetConnectionsFilterScreenAr._(_root); - @override late final _StringsNetConnectionsScreenAr NetConnectionsScreen = _StringsNetConnectionsScreenAr._(_root); - @override late final _StringsPerAppAndroidScreenAr PerAppAndroidScreen = _StringsPerAppAndroidScreenAr._(_root); - @override late final _StringsQrcodeScreenAr QrcodeScreen = _StringsQrcodeScreenAr._(_root); - @override late final _StringsRegionSettingsScreenAr RegionSettingsScreen = _StringsRegionSettingsScreenAr._(_root); - @override late final _StringsServerSelectScreenAr ServerSelectScreen = _StringsServerSelectScreenAr._(_root); - @override late final _StringsSettingsScreenAr SettingsScreen = _StringsSettingsScreenAr._(_root); - @override late final _StringsSpeedTestSettingsScreenAr SpeedTestSettingsScreen = _StringsSpeedTestSettingsScreenAr._(_root); - @override late final _StringsTextToQrCodeScreenAr TextToQrCodeScreen = _StringsTextToQrCodeScreenAr._(_root); - @override late final _StringsUrlTestSettingsScreenAr UrlTestSettingsScreen = _StringsUrlTestSettingsScreenAr._(_root); - @override late final _StringsUserAgreementScreenAr UserAgreementScreen = _StringsUserAgreementScreenAr._(_root); - @override late final _StringsVersionUpdateScreenAr VersionUpdateScreen = _StringsVersionUpdateScreenAr._(_root); - @override late final _StringsCommonWidgetAr CommonWidget = _StringsCommonWidgetAr._(_root); - @override late final _StringsServerManagerAr ServerManager = _StringsServerManagerAr._(_root); - @override late final _StringsMainAr main = _StringsMainAr._(_root); - @override String get enable => 'يُمكَِن'; - @override String get disable => 'إبطال'; - @override String get prefer => 'أولوية'; - @override String get only => 'فقط'; - @override String get open => 'يفتح'; - @override String get close => 'إنهاء'; - @override String get quit => 'يترك'; - @override String get add => 'اضف إليه'; - @override String get remove => 'يمسح'; - @override String get edit => 'يحرر'; - @override String get view => 'يفحص'; - @override String get more => 'أكثر'; - @override String get addProfile => 'إضافة ملف تعريف'; - @override String get addSuccess => 'اضيف بنجاح'; - @override String addSuccessThen({required Object p}) => 'تم إنشاء التكوين بنجاح، يرجى الانتقال إلى [${p}] للعرض'; - @override String addFailed({required Object p}) => 'إضافة فشل:${p}'; - @override String get removeConfirm => 'هل انت متأكد من الحذف؟'; - @override String get tips => 'معلومات'; - @override String get copy => 'ينسخ'; - @override String get ok => 'نعم'; - @override String get cancel => 'يلغي'; - @override String get feedback => 'تعليق'; - @override String get faq => 'أسئلة مكررة'; - @override String get download => 'تحميل'; - @override String get loading => 'تحميل...'; - @override String updateFailed({required Object p}) => 'فشل التحديث:${p}'; - @override String get days => 'أيام'; - @override String get hours => 'ساعات'; - @override String get minutes => 'دقائق'; - @override String get seconds => 'ثانية'; - @override String get protocol => 'بروتوكول'; - @override String get search => 'يبحث'; - @override String get custom => 'مخصص'; - @override String get connect => 'يتصل'; - @override String get disconnect => 'قطع الاتصال'; - @override String get connected => 'متصل'; - @override String get disconnected => 'انقطع الاتصال'; - @override String get connecting => 'توصيل'; - @override String get connectTimeout => 'ربط مهلة'; - @override String get timeout => 'نفذ الوقت'; - @override String get language => 'لغة'; - @override String get next => 'التالي'; - @override String get done => 'منتهي'; - @override String get apply => 'يتقدم'; - @override String get refresh => 'ينعش'; - @override String get retry => 'إعادة المحاولة?'; - @override String get none => 'لا أحد'; - @override String get reset => 'إعادة ضبط'; - @override String get submit => 'يُقدِّم'; - @override String get account => 'حساب'; - @override String get password => 'كلمة المرور'; - @override String get required => 'مطلوب'; - @override String get diversion => 'تحويل'; - @override String get diversionRules => 'قواعد التحويل'; - @override String get diversionRulesEnable => 'تمكين قواعد تفريغ [ISP]'; - @override String get diversionCustomGroup => 'مجموعة تحويل مخصصة'; - @override String get diversionCustomGroupPreset => 'الإعداد المسبق [مجموعة تحويل مخصصة]'; - @override String get diversionCustomGroupPresetTips => 'ملاحظة: ستتم إضافة/تغطية العناصر الممكّنة إلى [مجموعة التحويل المخصصة] و[قواعد التحويل]'; - @override String get diversionCustomGroupAddTips => 'ملاحظة: قد تحتاج إلى ضبط الفرز يدويًا بعد إضافته، وإلا فإن التحويل المضاف حديثًا قد لا يسري مفعوله.'; - @override String get urlTestCustomGroup => 'مجموعة الوكيل المخصصة'; - @override String get rulesetEnableTips => 'نصيحة: بعد تشغيل الخيارات ، يرجى الانتقال إلى [قواعد التحويل] لتعيين القواعد ذات الصلة ، وإلا فلن تدخل ساري المفعول '; - @override String get ispUserAgentTips => 'سيقدم [ISP] أنواعًا مختلفة من بيانات الاشتراك بناءً على [UserAgent] في طلب [HTTP].'; - @override String get ispDiversionTips => 'قواعد التفريغ التي يوفرها [ISP]؛ لا تدعم الاشتراكات من النوع [V2Ray] قواعد التفريغ'; - @override String get staticIP => 'رقم تعريف حاسوب ثابت'; - @override String get other => 'آخر'; - @override String get dns => 'DNS'; - @override String get url => 'URL'; - @override String get isp => 'ISP'; - @override String get tls => 'TLS'; - @override String get userAgent => 'UserAgent'; - @override String get urlInvalid => 'URL غير صالح'; - @override String get outboundActionCurrentSelected => 'المحدد الحالي'; - @override String get outboundActionUrltest => 'اختيار آلي'; - @override String get outboundActionDirect => 'مباشر'; - @override String get outboundActionBlock => 'حاجز'; - @override String get routeFinal => 'أخير'; - @override String get rulesetGeoSite => 'GeoSite'; - @override String get rulesetGeoIp => 'GeoIP'; - @override String get rulesetAcl => 'ACL'; - @override String get iCloud => 'iCloud'; - @override String get appleTV => 'Apple TV'; - @override String get webdav => 'Webdav'; - @override String get setting => 'إعدادات'; - @override String get protocolSniff => 'الكشف عن البروتوكول'; - @override String get protocolSniffOverrideDestination => 'يغطي اسم المجال المكتشف عنوان هدف الاتصال'; - @override String get remark => 'ملاحظة'; - @override String get remarkCannotEmpty => 'لا يمكن أن تكون الملاحظات فارغة'; - @override String get remarkTooLong => 'ملاحظات تصل إلى 32 حرفًا'; - @override String get remarkExist => 'ملاحظة موجودة بالفعل ، يرجى استخدام اسم آخر'; - @override String get domainSuffix => 'لاحقة اسم المجال'; - @override String get domain => 'اسم النطاق'; - @override String get domainKeyword => 'الكلمات الرئيسية لاسم المجال'; - @override String get domainRegex => 'انتظام اسم المجال'; - @override String get ip => 'IP'; - @override String get port => 'ميناء'; - @override String get appPackage => 'اسم حزمة التطبيق'; - @override String get processName => 'اسم العملية'; - @override String get processPath => 'مسار العملية'; - @override String get systemProxy => 'وكيل النظام'; - @override String get netInterfaces => 'واجهات صافية'; - @override String get netSpeed => 'سرعة'; - @override String get website => 'موقع إلكتروني'; - @override String get rule => 'قاعدة'; - @override String get global => 'عالمي'; - @override String get qrcode => 'رمز الاستجابة السريعة'; - @override String get scanQrcode => 'مسح رمز الاستجابة السريعة'; - @override String get scanResult => 'نتيجة المسح'; - @override String get backupAndSync => 'النسخ الاحتياطي والمزامنة'; - @override String get importAndExport => 'استيراد وتصدير'; - @override String get import => 'يستورد'; - @override String get export => 'يصدّر'; - @override String get termOfUse => 'شرط الخدمة'; - @override String get privacyPolicy => 'سياسة الخصوصية'; - @override String get about => 'عن'; - @override String get name => 'اسم'; - @override String get version => 'إصدار'; - @override String get notice => 'يلاحظ'; - @override String get sort => 'إعادة ترتيب'; - @override String get novice => 'وضع المبتدئ'; - @override String get recommended => 'يوصي'; - @override String innerError({required Object p}) => 'خطأ داخلي: ${p}'; - @override String get logicOperation => 'عملية منطقية'; - @override String get share => 'يشارك'; - @override String get candidateWord => 'كلمات المرشح'; - @override String get keywordsOrRegx => 'الكلمات الرئيسية/العادية'; - @override String get importFromClipboard => 'استيراد من الحافظة'; - @override String get exportToClipboard => 'تصدير إلى الحافظة'; - @override String get server => 'الخادم'; - @override String get appleTVConnectTurnOfprivateDirect => 'يرجى تمكين [الاتصال المباشر بالشبكة الخاصة] أولاً'; - @override String targetConnectFailed({required Object p}) => 'فشل الاتصال بـ [${p}]، يرجى التأكد من وجود الجهاز في نفس الشبكة المحلية (LAN) وتمكين [الاتصال المباشر بالشبكة الخاصة]'; - @override String get appleTVSync => 'مزامنة التكوين الأساسي الحالي مع Apple TV - Karing'; - @override String get appleTVSyncDone => 'اكتملت المزامنة، برجاء الانتقال إلى Apple TV - Karing لفتح/إعادة تشغيل الاتصال'; - @override String get appleTVRemoveCoreConfig => 'إزالة Apple TV - Karing Core Configuration'; - @override String get appleTVRemoveCoreConfigDone => 'Apple TV - تم حذف الملف التعريفي الأساسي لـ Karing؛ وتم قطع اتصال خدمة VPN'; - @override String get appleTVUrlInvalid => 'عنوان URL غير صالح، يرجى فتح Apple TV - Karing، ومسح رمز QR الذي يعرضه Karing'; - @override String get remoteProfileEditConfirm => 'بعد تحديث التكوين، ستتم استعادة تعديلات العقدة. هل تريد المتابعة؟'; - @override String invalidFileType({required Object p}) => 'نوع الملف غير صالح:${p}'; - @override Map get locales => { - 'en': 'English', - 'zh-CN': '简体中文', - 'ar': 'عربي', - 'ru': 'Русский', - 'fa': 'فارسی', - }; -} - -// Path: AboutScreen -class _StringsAboutScreenAr implements _StringsAboutScreenEn { - _StringsAboutScreenAr._(this._root); - - @override final _StringsAr _root; // ignore: unused_field - - // Translations - @override String get installRefer => 'تثبيت الرجوع'; - @override String get versionChannel => 'تحديث القنوات تلقائيا'; - @override String get disableUAReport => 'قم بإيقاف تشغيل تقرير بيانات الإجراء'; - @override String get disableUAReportTip => 'تساعدنا تقارير البيانات السلوكية على تحسين تجربة المنتج؛ ستقوم الإصدارات الأقل من الإصدار الرئيسي بإيقاف تشغيل جميع تقارير البيانات تلقائيًا (باستثناء [تنشيط التطبيق])'; - @override String get devOptions => 'خيارات للمطور'; - @override String get enableDebugLog => 'تمكين سجل التصحيح'; - @override String get viewFilsContent => 'عرض الملفات'; - @override String get enablePprof => 'يُمكَِن pprof'; - @override String get pprofPanel => 'pprof لوحة'; - @override String get openDir => 'فتح دليل الملف'; - @override String get useOriginalSBProfile => 'استخدم تكوين صندوق الغناء الأصلي'; -} - -// Path: AddProfileByImportFromFileScreen -class _StringsAddProfileByImportFromFileScreenAr implements _StringsAddProfileByImportFromFileScreenEn { - _StringsAddProfileByImportFromFileScreenAr._(this._root); - - @override final _StringsAr _root; // ignore: unused_field - - // Translations - @override String get title => 'استيراد ملف الملف الشخصي'; - @override String get chooseFile => 'حدد الملف'; - @override String get configExist => 'الملف الشخصي موجود بالفعل ، من فضلك لا تضيفه مرارًا وتكرارًا'; -} - -// Path: AddProfileByLinkOrContentScreen -class _StringsAddProfileByLinkOrContentScreenAr implements _StringsAddProfileByLinkOrContentScreenEn { - _StringsAddProfileByLinkOrContentScreenAr._(this._root); - - @override final _StringsAr _root; // ignore: unused_field - - // Translations - @override String get title => 'إضافة رابط ملف التعريف'; - @override String get updateTimerInterval => 'الفاصل الزمني للتحديث'; - @override String get updateTimerIntervalTips => 'لتعطيل من فضلك ضبط على:<5m'; - @override String get profileLinkContent => 'رابط/محتوى الملف الشخصي'; - @override String get profileLinkContentHit => 'ارتباط ملف التعريف/المحتوى [مطلوب] (دعم الدعم ، V2Ray (مدعوم الدفعة) ، خبأ ، karing ، sing-box ، shadowsocks ، روابط الملف الشخصي الفرعي)'; - @override String get subscriptionCannotEmpty => 'لا يمكن أن يكون رابط الملف الشخصي فارغًا'; - @override String get configExist => 'الملف الشخصي موجود بالفعل ، من فضلك لا تضيفه مرارًا وتكرارًا'; - @override String get invalidUrl => 'رابط الملف الطويل جدًا'; - @override String addFailedFormatException({required Object p}) => 'التنسيق خاطئ ، يرجى تصحيحه وإضافته مرة أخرى:${p}'; - @override String addFailedThenDownloadAndImport({required Object p}) => 'فشلت إضافة: ${p}، يرجى محاولة تعديل [UserAgent] والمحاولة مرة أخرى، أو استخدم المتصفح الخاص بالجهاز لفتح رابط التكوين واستيراد ملف التكوين الذي تم تنزيله بواسطة المتصفح إلى هذا التطبيق'; - @override String addFailedHandshakeException({required Object p}) => 'فشلت إضافة: ${p}، يرجى فتح الوكيل أو تعديل عقدة الوكيل الحالية والمحاولة مرة أخرى'; -} - -// Path: AddProfileByScanQrcodeScanScreen -class _StringsAddProfileByScanQrcodeScanScreenAr implements _StringsAddProfileByScanQrcodeScanScreenEn { - _StringsAddProfileByScanQrcodeScanScreenAr._(this._root); - - @override final _StringsAr _root; // ignore: unused_field - - // Translations - @override String get copy => 'Copy Link'; - @override String get open => 'Open Link'; - @override String get requestCameraPermission => 'يرجى تمكين إذن الكاميرا'; - @override String get requestScreenAccess => 'يرجى الانتقال إلى إعدادات النظام - الخصوصية والأمان - تسجيل الشاشة لإضافة أذونات لهذا التطبيق'; - @override String get screenshot => 'لقطة شاشة'; - @override String get scanFromImage => 'مسح من الصورة'; - @override String get scanNoResult => 'فشل في تحليل الصورة ، يرجى التأكد من أن لقطة الشاشة هي رمز QR صالح'; - @override String get scanEmptyResult => 'نتيجة الفحص فارغة'; - @override String scanException({required Object p}) => 'فشل في تحليل الصورة ، يرجى التأكد من أن لقطة الشاشة هي رمز QR صالح: ${p}'; -} - -// Path: BackupAndSyncLanSyncScreen -class _StringsBackupAndSyncLanSyncScreenAr implements _StringsBackupAndSyncLanSyncScreenEn { - _StringsBackupAndSyncLanSyncScreenAr._(this._root); - - @override final _StringsAr _root; // ignore: unused_field - - // Translations - @override String get title => 'LAN SYNC'; - @override String get lanSyncNotQuitTips => 'لا تخرج من هذه الواجهة قبل اكتمال التزامن'; -} - -// Path: BackupAndSyncWebdavScreen -class _StringsBackupAndSyncWebdavScreenAr implements _StringsBackupAndSyncWebdavScreenEn { - _StringsBackupAndSyncWebdavScreenAr._(this._root); - - @override final _StringsAr _root; // ignore: unused_field - - // Translations - @override String get webdavServerUrl => 'عنوان URL الخادم'; - @override String get webdavRequired => 'لايمكن ان يكون فارغا'; - @override String get webdavLoginFailed => 'فشل تسجيل الدخول:'; - @override String get webdavListFailed => 'فشل في الحصول على قائمة الملفات:'; -} - -// Path: DiversionGroupCustomEditScreen -class _StringsDiversionGroupCustomEditScreenAr implements _StringsDiversionGroupCustomEditScreenEn { - _StringsDiversionGroupCustomEditScreenAr._(this._root); - - @override final _StringsAr _root; // ignore: unused_field - - // Translations - @override String invalidDomain({required Object p}) => 'غير صالح [Domain]:${p}'; - @override String invalidIpCidr({required Object p}) => 'غير صالح [IP Cidr]:${p}'; - @override String invalidPort({required Object p}) => 'غير صالح [Port]:${p}'; - @override String invalidRuleSet({required Object p}) => 'غير صالح [Rule Set]:${p}, يجب أن يكون عنوان URL عنوان URL HTTPS صالحًا وملفًا ثنائيًا مع ملحق الملف .SRS'; - @override String invalidRuleSetBuildIn({required Object p}) => 'غير صالح [Rule Set(build-in)]:${p} غير صالحة، التنسيق هو geosite:xxx أو geoip:xxx أو acl:xxx، ويجب أن يكون xxx اسم قاعدة صالحًا'; - @override String get setDiversionRule => 'نصيحة: بعد الحفظ، يرجى الانتقال إلى [قواعد التحويل] لتعيين القواعد ذات الصلة، وإلا فلن تصبح سارية المفعول.'; -} - -// Path: DiversionRuleDetectScreen -class _StringsDiversionRuleDetectScreenAr implements _StringsDiversionRuleDetectScreenEn { - _StringsDiversionRuleDetectScreenAr._(this._root); - - @override final _StringsAr _root; // ignore: unused_field - - // Translations - @override String get title => 'قاعدة التحويل اكتشف'; - @override String get detect => 'يكشف'; - @override String get rule => 'قاعدة:'; - @override String get outbound => 'مخدم بروكسي:'; -} - -// Path: DiversionRulesScreen -class _StringsDiversionRulesScreenAr implements _StringsDiversionRulesScreenEn { - _StringsDiversionRulesScreenAr._(this._root); - - @override final _StringsAr _root; // ignore: unused_field - - // Translations - @override String get diversionRulesMatchTips => 'نصيحة: حاول مطابقة القواعد من الأعلى إلى الأسفل، إذا لم تتم مطابقة أي قاعدة، استخدم [نهائي]'; -} - -// Path: DnsSettingsScreen -class _StringsDnsSettingsScreenAr implements _StringsDnsSettingsScreenEn { - _StringsDnsSettingsScreenAr._(this._root); - - @override final _StringsAr _root; // ignore: unused_field - - // Translations - @override String get ispCanNotEmpty => 'لا يمكن أن يكون ISP فارغًا'; - @override String get urlCanNotEmpty => 'لا يمكن أن يكون عنوان URL فارغًا'; - @override String error({required Object p}) => 'نوع غير مدعوم:${p}'; - @override String get dnsDesc => 'العمود الأول من بيانات التأخير هو تأخير استعلام الاتصال المباشر;\nالعمود الثاني: شغله [[حركة الوكيل]حل DNS من خلال خادم الوكيل]: بيانات التأخير هي تأخير الاستعلام الذي تم إعادة توجيهه من خلال خادم الوكيل الحالي; إذا [[حركة الوكيل]حل DNS من خلال خادم الوكيل]: بيانات التأخير هي تأخير استعلام الاتصال المباشر'; -} - -// Path: FeedbackScreen -class _StringsFeedbackScreenAr implements _StringsFeedbackScreenEn { - _StringsFeedbackScreenAr._(this._root); - - @override final _StringsAr _root; // ignore: unused_field - - // Translations - @override String get content => 'محتوى ردود الفعل'; - @override String get contentHit => 'مطلوب ، ما يصل إلى 500 حرف'; - @override String get contentCannotEmpty => 'لا يمكن أن يكون محتوى التعليقات فارغًا'; -} - -// Path: FileContentViewerScreen -class _StringsFileContentViewerScreenAr implements _StringsFileContentViewerScreenEn { - _StringsFileContentViewerScreenAr._(this._root); - - @override final _StringsAr _root; // ignore: unused_field - - // Translations - @override String get title => 'ملف محتوى الملف'; - @override String get chooseFile => 'حدد الملف'; - @override String get clearFileContent => 'هل أنت متأكد من مسح محتوى الملف؟'; - @override String get clearFileContentTips => 'هل أنت متأكد من مسح محتوى ملف الملف الشخصي؟قد يتسبب تطهير ملف الملف الشخصي في فقدان البيانات أو وظائف التطبيق غير الطبيعية ، يرجى العمل بحذر'; -} - -// Path: HomeScreen -class _StringsHomeScreenAr implements _StringsHomeScreenEn { - _StringsHomeScreenAr._(this._root); - - @override final _StringsAr _root; // ignore: unused_field - - // Translations - @override String get toSelectServer => 'الرجاء تحديد خادم'; - @override String get invalidServer => 'غير صالح ، الرجاء اختيار مرة أخرى'; - @override String get disabledServer => 'معطل ، الرجاء اختيار مرة أخرى'; - @override String get expiredServer => 'لا يوجد خادم متاح: قد يكون التكوين قديمًا أو معطلاً'; - @override String systemProxyTips({required Object sp, required Object hp}) => 'جوارب:${sp},http(s):${hp}'; - @override String get trafficTotal => 'إجمالي حركة المرور'; - @override String get trafficProxy => 'وكيل حركة المرور'; - @override String get myLinkEmpty => 'الرجاء الإعداد [الاختصار وصلة] قبل استخدامه'; - @override String get deviceNoSpace => 'مساحة غير كافيه في القرص'; - @override String tooMuchServers({required Object p, required Object p1}) => 'يوجد عدد كبير جدًا من الخوادم الوكيلة [${p}>${p1}]، وقد لا يكون الاتصال ممكنًا بسبب قيود ذاكرة النظام.'; -} - -// Path: LaunchFailedScreen -class _StringsLaunchFailedScreenAr implements _StringsLaunchFailedScreenEn { - _StringsLaunchFailedScreenAr._(this._root); - - @override final _StringsAr _root; // ignore: unused_field - - // Translations - @override String get invalidProcess => 'فشل التطبيق في البدء [اسم عملية غير صالح] ، يرجى إعادة تثبيت التطبيق إلى دليل منفصل'; - @override String get invalidProfile => 'فشل التطبيق في البدء [فشل في الوصول إلى الملف الشخصي] ، يرجى إعادة تثبيت التطبيق'; - @override String get invalidVersion => 'فشل التطبيق في بدء [إصدار غير صالح] ، يرجى إعادة تثبيت التطبيق'; - @override String get systemVersionLow => 'فشل بدء تشغيل التطبيق [إصدار النظام منخفض جدًا]'; - @override String get startFromUNC => 'مسار التثبيت غير صالح ، يرجى إعادة تثبيته إلى مسار صالح'; -} - -// Path: MyProfilesEditScreen -class _StringsMyProfilesEditScreenAr implements _StringsMyProfilesEditScreenEn { - _StringsMyProfilesEditScreenAr._(this._root); - - @override final _StringsAr _root; // ignore: unused_field - - // Translations - @override String get title => 'تحرير الملف الشخصي'; - @override String get urlExist => 'عنوان URL موجود بالفعل ، يرجى استخدام عنوان URL آخر'; - @override String get updateTimerInterval => 'الفاصل الزمني للتحديث'; - @override String get updateTimerIntervalTips => 'لتعطيل يرجى تعيين:<5m'; - @override String get reloadAfterProfileUpdate => 'إعادة التحميل بعد تحديث الملف الشخصي'; - @override String get testLatencyAfterProfileUpdate => 'ابدأ اختبارات الكمون بعد التحديث تلقائيًا'; - @override String get testLatencyAfterProfileUpdateTips => 'يجب توصيل VPN ، وتمكين [إعادة التحميل بعد تحديث الملف الشخصي]'; - @override String get testLatencyAutoRemove => 'إزالة الخوادم التي تفشل تلقائيا اختبارات الكمون'; - @override String get testLatencyAutoRemoveTips => 'جرب ما يصل إلى 3 مرات'; -} - -// Path: MyProfilesMergeScreen -class _StringsMyProfilesMergeScreenAr implements _StringsMyProfilesMergeScreenEn { - _StringsMyProfilesMergeScreenAr._(this._root); - - @override final _StringsAr _root; // ignore: unused_field - - // Translations - @override String get profilesMerge => 'دمج الملامح'; - @override String get profilesMergeTarget => 'ملف تعريف الهدف'; - @override String get profilesMergeSource => 'ملفات تعريف المصدر'; - @override String get profilesMergeTips => 'نصيحة: سيتم تجاهل تحويل ملفات تعريف المصدر'; -} - -// Path: MyProfilesScreen -class _StringsMyProfilesScreenAr implements _StringsMyProfilesScreenEn { - _StringsMyProfilesScreenAr._(this._root); - - @override final _StringsAr _root; // ignore: unused_field - - // Translations - @override String get title => 'مظهر'; - @override String get atLeastOneEnable => 'لا يمكن تعطيله ، يرجى الاحتفاظ بملف تعريف واحد على الأقل'; -} - -// Path: NetCheckScreen -class _StringsNetCheckScreenAr implements _StringsNetCheckScreenEn { - _StringsNetCheckScreenAr._(this._root); - - @override final _StringsAr _root; // ignore: unused_field - - // Translations - @override String get title => 'فحص صافي'; - @override String get warn => 'ملاحظة: نظرًا لتأثير بيئة الشبكة وقواعد التحويل ، فإن نتائج الاختبار ليست مكافئة تمامًا للنتائج الفعلية.'; - @override String get check => 'يفحص'; - @override String get invalidDomain => 'اسم النطاق غير صالح'; - @override String get connectivity => 'اتصال الشبكة'; - @override String connectivityTestIpv4AllFailed({required Object p}) => 'اختبار اتصال IPv4[${p}] كل شيء فشل'; - @override String get connectivityTestIpv4Ok => 'Ipv4 نجح الاتصال'; - @override String connectivityTestIpv6AllFailed({required Object p}) => 'Ipv6 اختبار الاتصال [${p}] كل شيء فشل ، قد لا تدعم شبكتك IPv6'; - @override String get connectivityTestIpv6Ok => 'نجح اتصال IPv6'; - @override String get connectivityTestOk => 'الشبكة متصلة بالإنترنت'; - @override String get connectivityTestFailed => 'الشبكة ليست متصلة بعد بالإنترنت'; - @override String get remoteRulesetsDownloadOk => 'تم تنزيل كل شيء بنجاح'; - @override String get remoteRulesetsDownloadNotOk => 'التحميل أو فشل'; - @override String get outbound => 'مخدم بروكسي'; - @override String outboundOk({required Object p}) => '[${p}] نجح الاتصال '; - @override String outboundFailed({required Object p1, required Object p2}) => '[${p1}] فشل الاتصال\nError:[${p2}]'; - @override String get dnsServer => 'DNS الخادم'; - @override String dnsOk({required Object p1, required Object p2, required Object p3, required Object p4}) => '[${p1}]نجح استعلام DNS\nDNS قاعدة:[${p2}]\n وقت الإستجابة:[${p3} ms]\nAعنوان[${p4}]'; - @override String dnsFailed({required Object p1, required Object p2, required Object p3}) => '[${p1}]نجح استعلام DNS\n nDNS قاعدة:[${p2}]\nخطأ:[${p3}]'; - @override String get host => 'اتصال HTTP'; - @override String hostConnection({required Object p1, required Object p2, required Object p3}) => '[${p1}]\nقاعدة التحويل:[${p2}]\nمخدم بروكسي:[${p3}]'; - @override String get hostConnectionOk => 'نجح الاتصال'; - @override String hostConnectionFailed({required Object p}) => 'فشل الاتصال:[${p}]'; -} - -// Path: NetConnectionsFilterScreen -class _StringsNetConnectionsFilterScreenAr implements _StringsNetConnectionsFilterScreenEn { - _StringsNetConnectionsFilterScreenAr._(this._root); - - @override final _StringsAr _root; // ignore: unused_field - - // Translations - @override String get title => 'تصفية الاتصالات'; - @override String get hostIp => 'المجال/IP'; - @override String get app => 'برنامج'; - @override String get rule => 'قاعدة'; - @override String get chain => 'خارج'; -} - -// Path: NetConnectionsScreen -class _StringsNetConnectionsScreenAr implements _StringsNetConnectionsScreenEn { - _StringsNetConnectionsScreenAr._(this._root); - - @override final _StringsAr _root; // ignore: unused_field - - // Translations - @override String get title => 'روابط'; - @override String get copyAsCSV => 'نسخ إلى تنسيق CSV'; - @override String get selectType => 'حدد نوع التحويل'; -} - -// Path: PerAppAndroidScreen -class _StringsPerAppAndroidScreenAr implements _StringsPerAppAndroidScreenEn { - _StringsPerAppAndroidScreenAr._(this._root); - - @override final _StringsAr _root; // ignore: unused_field - - // Translations - @override String get title => 'لكل وكيل تطبيق'; - @override String get whiteListMode => 'وضع القائمة البيضاء'; - @override String get whiteListModeTip => 'عند التمكين: فقط التطبيقات التي تم فحصها هي وكلاء ؛عندما لا يتم تمكينها: فقط التطبيقات التي لم يتم فحصها هي وكلاء'; - @override String get hideSystemApp => 'إخفاء تطبيقات النظام'; - @override String get hideAppIcon => 'إخفاء أيقونة التطبيق'; - @override String get enableAppQueryPermission => 'قم بتشغيل الإذن [استعلام قائمة التطبيقات]'; -} - -// Path: QrcodeScreen -class _StringsQrcodeScreenAr implements _StringsQrcodeScreenEn { - _StringsQrcodeScreenAr._(this._root); - - @override final _StringsAr _root; // ignore: unused_field - - // Translations - @override String get tooLong => 'النص طويل جدًا لعرضه'; - @override String get copy => 'نسخ الوصلة'; - @override String get open => 'افتح الرابط'; - @override String get share => 'شارك الرابط'; - @override String get shareImage => 'شارك رمز الاستجابة السريعة'; -} - -// Path: RegionSettingsScreen -class _StringsRegionSettingsScreenAr implements _StringsRegionSettingsScreenEn { - _StringsRegionSettingsScreenAr._(this._root); - - @override final _StringsAr _root; // ignore: unused_field - - // Translations - @override String get title => 'الدولة او المنطقة'; - @override String get Regions => ' نصيحة: يرجى تعيين بلدك أو منطقتك الحالية بشكل صحيح ، وإلا فقد يتسبب في مشاكل في تحويل الشبكة'; -} - -// Path: ServerSelectScreen -class _StringsServerSelectScreenAr implements _StringsServerSelectScreenEn { - _StringsServerSelectScreenAr._(this._root); - - @override final _StringsAr _root; // ignore: unused_field - - // Translations - @override String get title => 'حدد الخادم'; - @override String get autoSelectServer => 'تلقائي حدد الخادم بأقل زمن انتقال'; - @override String get recentUse => 'مستخدم حديثا'; - @override String get myFav => 'المفضل لدي'; - @override String selectLocal({required Object p}) => 'الخادم المحدد هو عنوان محلي وقد لا يعمل بشكل صحيح:${p}'; - @override String get selectRequireEnableIPv6 => 'الخادم المحدد هو عنوان IPv6 ويتطلب [تمكين IPv6]'; - @override String get selectDisabled => 'تم تعطيل هذا الخادم'; - @override String get error404 => 'واجه اكتشاف الكمون خطأ ، يرجى التحقق مما إذا كان هناك تكوين مع نفس المحتوى'; -} - -// Path: SettingsScreen -class _StringsSettingsScreenAr implements _StringsSettingsScreenEn { - _StringsSettingsScreenAr._(this._root); - - @override final _StringsAr _root; // ignore: unused_field - - // Translations - @override String ispFaq({required Object p}) => 'أسئلة مكررة[${p}]'; - @override String cleanISP({required Object p}) => 'ISP واضح[${p}]'; - @override String get openISP => 'فتح ISP رابط'; - @override String get cleanISPNoParam => 'مسح معلومات مزود خدمة الإنترنت '; - @override String get getTranffic => 'احصل على حركة المرور'; - @override String get tutorial => 'درس تعليمي'; - @override String get commonlyUsedRulesets => 'مجموعات القواعد شائعة الاستخدام'; - @override String get howToRemoveAds => 'كيفية إزالة الإعلانات'; - @override String get htmlBoard => 'لوحة على الانترنت'; - @override String get dnsLeakDetection => 'كشف تسرب DNS'; - @override String get speedTest => 'اختبار السرعة'; - @override String get downloadProfilePreferProxy => 'تفضل الوكيل لتنزيل الملف الشخصي'; - @override String get downloadProfilePreferProxyTips => 'إذا كان متصلاً حاليًا ، فسيتم تنزيل الملف الشخصي من خلال الوكيل المتصالح أولاً'; - @override String get rulesetDirectDownlad => 'مجموعة القواعد تحميل مباشر'; - @override String get hideUnusedDiversionGroup => 'إخفاء مجموعات التحويل غير المستخدمة'; - @override String get disableISPDiversionGroup => 'تعطيل قواعد تحويل ISP'; - @override String get portSetting => 'ميناء'; - @override String get portSettingRule => 'القاعدة القائمة'; - @override String get portSettingDirectAll => 'توجيه كل شيء'; - @override String get portSettingProxyAll => 'وكيل الكل'; - @override String get portSettingControl => 'السيطرة والمزامنة'; - @override String get portSettingCluster => 'خدمة الكتلة'; - @override String get modifyPort => 'تعديل المنفذ'; - @override String get ipStrategyTips => 'قبل التمكين ، يرجى تأكيد أن شبكتك تدعم IPv6 ، وإلا لا يمكن الوصول إلى بعض حركة المرور بشكل طبيعي.'; - @override String get tunAppendHttpProxy => 'إلحاق وكيل HTTP إلى VPN'; - @override String get tunAppendHttpProxyTips => 'ستجاوز بعض التطبيقات جهاز NIC الظاهري والاتصال مباشرة بوكيل HTTP'; - @override String get tlsInsecureEnable => 'تخطي التحقق من الشهادة'; - @override String get tlsFragmentEnable => 'تمكين تجزئة TLS'; - @override String get tlsFragmentSize => 'حجم شريحة TLS'; - @override String get tlsFragmentSleep => 'TLS النوم المجزأ'; - @override String get tlsMixedCaseSNIEnable => 'تمكين TLS الهجين SNI'; - @override String get tlsPaddingEnable => 'تمكين الحشو TLS'; - @override String get tlsPaddingSize => 'حجم الحشو TLS'; - @override String get dnsEnableRule => 'تمكين قواعد تحويل DNS'; - @override String get dnsEnableFakeIp => 'تمكين وهمية'; - @override String get dnsEnableClientSubnet => 'تمكين ECS'; - @override String get dnsEnableProxyResolveByProxy => '[حركة الوكيل] حل DNS من خلال خادم الوكيل'; - @override String get dnsEnableFinalResolveByProxy => '[نهائي] حل DNS من خلال خادم الوكيل'; - @override String get dnsTestDomain => 'مجال الاختبار'; - @override String get dnsTestDomainInvalid => 'مجال غير صالح'; - @override String get dnsTypeOutbound => 'مخدم بروكسي'; - @override String get dnsTypeDirect => 'سير مستقيم'; - @override String get dnsTypeProxy => 'حركة الوكيل'; - @override String get dnsTypeResolver => 'خادم DNS'; - @override String get dnsEnableRuleTips => 'بعد التمكين ، سيختار اسم المجال خادم DNS المقابل للدقة وفقًا لقواعد التحويل'; - @override String get dnsEnableFakeIpTips => 'بعد تمكين FakeIP، إذا تم قطع اتصال VPN، فقد يلزم إعادة تشغيل التطبيق الخاص بك؛ يجب تشغيل هذه الوظيفة [وضع TUN]'; - @override String get dnsTypeOutboundTips => 'دقة اسم المجال لخادم الوكيل'; - @override String get dnsTypeDirectTips => 'حل اسم المجال لحركة المرور المباشرة'; - @override String get dnsTypeProxyTips => 'حل اسم المجال لحركة المرور الوكيل'; - @override String get dnsTypeResolverTips => 'دقة اسم المجال لخادم DNS الآخر'; - @override String get dnsTypeFinalTips => 'حل اسم المجال لحركة المرور الأخرى'; - @override String get dnsAutoSetServer => 'إعداد الخادم تلقائيا'; - @override String get dnsResetServer => 'إعادة تعيين الخادم'; - @override String get inboundDomainResolve => 'حل أسماء النطاقات الواردة'; - @override String get privateDirect => 'اتصال مباشر بالشبكة الخاصة'; - @override String inboundDomainResolveTips({required Object p}) => 'تحتاج بعض أسماء النطاقات التي لا تحتوي على قواعد تحويل تم تكوينها إلى حلها قبل أن تتمكن من الوصول إلى قواعد التحويل المستندة إلى IP؛ وتؤثر هذه الميزة على الطلبات الواردة إلى منفذ الوكيل [${p}]'; - @override String get useRomoteRes => 'استخدم الموارد البعيدة'; - @override String get autoSelect => 'اختيار آلي'; - @override String get autoSelectServerIgnorePerProxyServer => 'تجاهل الخادم الوكيل [الوكيل الأمامي].'; - @override String get autoSelectServerInterval => 'فاصل الشيكات الكمون'; - @override String get autoSelectServerReTestIfNetworkUpdate => 'إعادة اكتشاف متى تتغير الشبكة'; - @override String get autoSelectServerUpdateCurrentServerAfterManualUrltest => 'قم بتحديث الخادم الحالي بعد الكشف اليدوي عن التأخير'; - @override String get autoSelectServerIntervalTips => 'كلما كان الفاصل الزمني لاكتشاف التأخير أقصر، كلما تم تحديث بيانات تأخير الخادم في الوقت المناسب، ولكنها ستشغل المزيد من الموارد وتستهلك الكهرباء بشكل أسرع'; - @override String get autoSelectServerFavFirst => 'PRI-Use [My Favs]'; - @override String get autoSelectServerFavFirstTips => 'إذا لم تكن قائمة [Favs] فارغة ، فاستخدم الخوادم في [Favs]'; - @override String get autoSelectServerFilter => 'تصفية خوادم غير صالحة'; - @override String autoSelectServerFilterTips({required Object p}) => 'سيتم تصفية حالات فشل الكشف عن تأخير الخادم؛ إذا لم يكن هناك خادم متاح بعد التصفية، فسيتم استخدام الخوادم [${p}] الأولى بدلاً من ذلك.'; - @override String get autoSelectServerLimitedNum => 'الحد الأقصى لعدد الخوادم'; - @override String get autoSelectServerLimitedNumTips => 'سيتم تصفية الخوادم التي تتجاوز هذا الرقم'; - @override String get numInvalid => 'رقم غير صالح'; - @override String get hideInvalidServer => 'إخفاء الخوادم غير الصالحة'; - @override String get sortServer => 'خوادم الفرز'; - @override String get sortServerTips => 'فرز حسب الكمون من منخفض إلى مرتفع'; - @override String get selectServerHideRecommand => 'إخفاء [يوصي]'; - @override String get selectServerHideRecent => 'إخفاء [المستخدمة مؤخرًا]'; - @override String get selectServerHideFav => 'إخفاء [المفضلة لدي]'; - @override String get homeScreen => 'الشاشة الرئيسية'; - @override String get theme => 'Tالهيم'; - @override String get myLink => 'ارتباط اختصار'; - @override String get myLinkInvalid => 'URL غير صالح'; - @override String get autoConnectAfterLaunch => 'اتصال السيارات بعد الإطلاق'; - @override String get hideAfterLaunch => 'إخفاء النافذة بعد بدء التشغيل'; - @override String get autoSetSystemProxy => 'وكيل نظام تعيين تلقائي عند الاتصال'; - @override String get disconnectWhenQuit => 'افصل عندما يخرج التطبيق'; - @override String get allowBypass => 'السماح للتطبيقات بتجاوز VPN'; - @override String get lanSyncTo => 'مزامنة للآخرين '; - @override String get lanSyncFrom => 'مزامنة من الآخرين'; - @override String get lanSyncScanQRcode => 'مسح رمز الاستجابة السريعة للمزامنة '; - @override String get syncToConfirm => 'هل تريد تأكيد المزامنة مع الطرف الآخر؟'; - @override String get syncDone => 'اكتملت المزامنة'; - @override String get importSuccess => 'استيراد نجاح '; - @override String get rewriteConfirm => 'سيقوم هذا الملف بكتابة التكوين المحلي الحالي.هل تريد الاستمرار؟'; - @override String get networkShare => 'مشاركة الشبكة'; - @override String get frontProxy => 'الوكيل الأمامي'; - @override String get frontProxyTips => 'بيانات->خادم الوكيل الأمامي->مخدم بروكسي->الخادم الهدف'; - @override String get allowOtherHostsConnect => 'اسمح للآخرين بالاتصال'; - @override String allowOtherHostsConnectTips({required Object sp, required Object hp}) => 'socks:${sp},http(s):${hp}'; - @override String get tunAutoRoute => 'Auto Route'; - @override String get tunStrictRoute => 'Strict Route'; - @override String get tunStrictRouteTips => 'إذا لم يتمكن الآخرون من الوصول إلى هذا الجهاز بعد تشغيل المشاركة، فيرجى محاولة إيقاف تشغيل هذا المفتاح.'; - @override String get enableCluster => 'تمكين مجموعة الوكيل الجوارب/HTTP'; - @override String get clusterAllowOtherHostsConnect => 'السماح للآخرين بالاتصال بـ CLUSTER'; - @override String clusterAllowOtherHostsConnectTips({required Object hp}) => 'http://127.0.0.1:${hp}/get_proxies'; - @override String get clusterAuth => 'مصادقة مجموعة الوكيل'; - @override String get clusterConfirm => 'يرجى التأكيد على أنه تم فحص زمن انتقال الخوادم ، ولن يتم إنشاء خدمات الوكيل إذا لم يتم فحصها أو فحصها بشكل غير صحيح'; - @override String get tunMode => 'نفق وضع'; - @override String get tunModeTips => 'سيتولى وضع TUN كل حركة مرور النظام [في هذا الوضع ، يمكنك ترك وكيل النظام غير مدقلة]'; - @override String get tunModeRunAsAdmin => 'يتطلب وضع TUN أذونات مسؤول النظام ، يرجى إعادة تشغيل التطبيق كمسؤول'; - @override String get tunStack => 'Stack'; - @override String get launchAtStartup => 'إطلاق عند بدء التشغيل'; - @override String get quitWhenSwitchSystemUser => 'خروج تطبيق عند تبديل مستخدمي النظام'; - @override String get handleScheme => 'مكالمة مخطط النظام'; - @override String get portableMode => 'الوضع المحمول'; - @override String get portableModeDisableTips => 'إذا كنت بحاجة إلى الخروج من الوضع المحمول، فيرجى الخروج من [karing] وحذف المجلد [profiles] يدويًا في نفس الدليل مثل [karing.exe]'; - @override String get handleKaringScheme => 'مقبض karing:// Call'; - @override String get handleClashScheme => 'مقبض clash:// Call'; - @override String get handleSingboxScheme => 'مقبض sing-box:// يتصل'; - @override String get removeSystemVPNConfig => 'حذف تكوين VPN النظام'; - @override String get timeConnectOrDisconnect => 'المقرر يتصل/قطع الاتصال'; - @override String get timeConnectOrDisconnectTips => 'يجب أن يكون VPN متصلاً ليصبح مفيدًا ؛بعد تشغيله ، سيتم تعطيل [النوم التلقائي]'; - @override String timeConnectAndDisconnectInterval({required Object p}) => 'ال cاتصاللا يمكن أن يكون فاصل الانفصال أقل من ${p} دقائق'; - @override String get disableFontScaler => 'تعطيل تحجيم الخط(إعادة التشغيل يسري)'; - @override String get autoOrientation => 'اتبع دوران الشاشة'; - @override String get restartTakesEffect => 'إعادة التشغيل يسري'; - @override String get resetSettings => 'اعادة الضبط'; - @override String get cleanCache => 'مسح ذاكرة التخزين المؤقت'; - @override String get cleanCacheDone => 'اكتملت عملية التنظيف'; - @override String get appleTestFlight => 'Apple Testflight'; - @override String get appleAppStore => 'متجر تطبيقات Apple'; - @override String hasNewVersion({required Object p}) => 'تحديث الإصدار ${p}'; - @override String get follow => 'تابعنا'; - @override String get contactUs => 'اتصل بنا'; - @override String get rateInApp => 'قيمنا'; - @override String get rateInAppStore => 'قيمنا في متجر التطبيقات'; -} - -// Path: SpeedTestSettingsScreen -class _StringsSpeedTestSettingsScreenAr implements _StringsSpeedTestSettingsScreenEn { - _StringsSpeedTestSettingsScreenAr._(this._root); - - @override final _StringsAr _root; // ignore: unused_field - - // Translations - @override String get title => 'URL اختبار السرعة'; - @override String get error => 'يجب أن يكون عنوان URL HTTPS صالح'; -} - -// Path: TextToQrCodeScreen -class _StringsTextToQrCodeScreenAr implements _StringsTextToQrCodeScreenEn { - _StringsTextToQrCodeScreenAr._(this._root); - - @override final _StringsAr _root; // ignore: unused_field - - // Translations - @override String get title => 'رسالة نصية إلى رمز الاستجابة السريعة'; - @override String get convert => 'يتحول'; -} - -// Path: UrlTestSettingsScreen -class _StringsUrlTestSettingsScreenAr implements _StringsUrlTestSettingsScreenEn { - _StringsUrlTestSettingsScreenAr._(this._root); - - @override final _StringsAr _root; // ignore: unused_field - - // Translations - @override String get title => 'عنوان URL لاكتشاف التأخير'; - @override String get error => 'يجب أن يكون عنوان URL HTTPS صالح'; -} - -// Path: UserAgreementScreen -class _StringsUserAgreementScreenAr implements _StringsUserAgreementScreenEn { - _StringsUserAgreementScreenAr._(this._root); - - @override final _StringsAr _root; // ignore: unused_field - - // Translations - @override String get privacyFirst => 'خصوصيتك تأتي أولا'; - @override String get agreeAndContinue => 'قبول ومتابعة'; -} - -// Path: VersionUpdateScreen -class _StringsVersionUpdateScreenAr implements _StringsVersionUpdateScreenEn { - _StringsVersionUpdateScreenAr._(this._root); - - @override final _StringsAr _root; // ignore: unused_field - - // Translations - @override String versionReady({required Object p}) => 'الإصدار الجديد [${p}] جاهز'; - @override String get update => 'أعد التشغيل للتحديث'; - @override String get cancel => 'ليس الآن'; -} - -// Path: CommonWidget -class _StringsCommonWidgetAr implements _StringsCommonWidgetEn { - _StringsCommonWidgetAr._(this._root); - - @override final _StringsAr _root; // ignore: unused_field - - // Translations - @override String get diableAlwayOnVPN => 'إذا تم تشغيل [Always on VPN]، فيرجى إيقاف تشغيل [Always on VPN] ومحاولة الاتصال مرة أخرى.'; - @override String get resetPort => 'الرجاء تغيير المنفذ إلى منفذ آخر متاح أو إغلاق التطبيق الذي يشغل المنفذ.'; -} - -// Path: ServerManager -class _StringsServerManagerAr implements _StringsServerManagerEn { - _StringsServerManagerAr._(this._root); - - @override final _StringsAr _root; // ignore: unused_field - - // Translations - @override String get noServerAvaliable => 'لا يوجد خادم متاح، يرجى التأكد من صلاحية رابط التكوين أو ملف التكوين؛ وإذا كان التكوين الخاص بك يأتي من GitHub، فيرجى الحصول على عنوان الرابط من الزر [Raw] الموجود في الصفحة'; - @override String get filePathCannotEmpty => 'لا يمكن أن يكون مسار الملف فارغًا'; - @override String fileNotExist({required Object p}) => 'الملف غير موجود: ${p}'; - @override String get urlCannotEmpty => 'لا يمكن أن يكون الرابط فارغًا'; - @override String get invalidUrl => 'رابط ملف تعريف غير صالح'; - @override String get parseFailed => 'فشل تحليل الملف الشخصي'; -} - -// Path: main -class _StringsMainAr implements _StringsMainEn { - _StringsMainAr._(this._root); - - @override final _StringsAr _root; // ignore: unused_field - - // Translations - @override late final _StringsMainTrayAr tray = _StringsMainTrayAr._(_root); -} - -// Path: main.tray -class _StringsMainTrayAr implements _StringsMainTrayEn { - _StringsMainTrayAr._(this._root); - - @override final _StringsAr _root; // ignore: unused_field - - // Translations - @override String get menuOpen => ' يفتح '; - @override String get menuExit => ' مخرج '; -} - -// Path: -class _StringsFa implements Translations { - /// You can call this constructor and build your own translation instance of this locale. - /// Constructing via the enum [AppLocale.build] is preferred. - _StringsFa.build({Map? overrides, PluralResolver? cardinalResolver, PluralResolver? ordinalResolver}) - : assert(overrides == null, 'Set "translation_overrides: true" in order to enable this feature.'), - $meta = TranslationMetadata( - locale: AppLocale.fa, - overrides: overrides ?? {}, - cardinalResolver: cardinalResolver, - ordinalResolver: ordinalResolver, - ) { - $meta.setFlatMapFunction(_flatMapFunction); - } - - /// Metadata for the translations of . - @override final TranslationMetadata $meta; - - /// Access flat map - @override dynamic operator[](String key) => $meta.getTranslation(key); - - @override late final _StringsFa _root = this; // ignore: unused_field - - // Translations - @override late final _StringsAboutScreenFa AboutScreen = _StringsAboutScreenFa._(_root); - @override late final _StringsAddProfileByImportFromFileScreenFa AddProfileByImportFromFileScreen = _StringsAddProfileByImportFromFileScreenFa._(_root); - @override late final _StringsAddProfileByLinkOrContentScreenFa AddProfileByLinkOrContentScreen = _StringsAddProfileByLinkOrContentScreenFa._(_root); - @override late final _StringsAddProfileByScanQrcodeScanScreenFa AddProfileByScanQrcodeScanScreen = _StringsAddProfileByScanQrcodeScanScreenFa._(_root); - @override late final _StringsBackupAndSyncLanSyncScreenFa BackupAndSyncLanSyncScreen = _StringsBackupAndSyncLanSyncScreenFa._(_root); - @override late final _StringsBackupAndSyncWebdavScreenFa BackupAndSyncWebdavScreen = _StringsBackupAndSyncWebdavScreenFa._(_root); - @override late final _StringsDiversionGroupCustomEditScreenFa DiversionGroupCustomEditScreen = _StringsDiversionGroupCustomEditScreenFa._(_root); - @override late final _StringsDiversionRuleDetectScreenFa DiversionRuleDetectScreen = _StringsDiversionRuleDetectScreenFa._(_root); - @override late final _StringsDiversionRulesScreenFa DiversionRulesScreen = _StringsDiversionRulesScreenFa._(_root); - @override late final _StringsDnsSettingsScreenFa DnsSettingsScreen = _StringsDnsSettingsScreenFa._(_root); - @override late final _StringsFeedbackScreenFa FeedbackScreen = _StringsFeedbackScreenFa._(_root); - @override late final _StringsFileContentViewerScreenFa FileContentViewerScreen = _StringsFileContentViewerScreenFa._(_root); - @override late final _StringsHomeScreenFa HomeScreen = _StringsHomeScreenFa._(_root); - @override late final _StringsLaunchFailedScreenFa LaunchFailedScreen = _StringsLaunchFailedScreenFa._(_root); - @override late final _StringsMyProfilesEditScreenFa MyProfilesEditScreen = _StringsMyProfilesEditScreenFa._(_root); - @override late final _StringsMyProfilesMergeScreenFa MyProfilesMergeScreen = _StringsMyProfilesMergeScreenFa._(_root); - @override late final _StringsMyProfilesScreenFa MyProfilesScreen = _StringsMyProfilesScreenFa._(_root); - @override late final _StringsNetCheckScreenFa NetCheckScreen = _StringsNetCheckScreenFa._(_root); - @override late final _StringsNetConnectionsFilterScreenFa NetConnectionsFilterScreen = _StringsNetConnectionsFilterScreenFa._(_root); - @override late final _StringsNetConnectionsScreenFa NetConnectionsScreen = _StringsNetConnectionsScreenFa._(_root); - @override late final _StringsPerAppAndroidScreenFa PerAppAndroidScreen = _StringsPerAppAndroidScreenFa._(_root); - @override late final _StringsQrcodeScreenFa QrcodeScreen = _StringsQrcodeScreenFa._(_root); - @override late final _StringsRegionSettingsScreenFa RegionSettingsScreen = _StringsRegionSettingsScreenFa._(_root); - @override late final _StringsServerSelectScreenFa ServerSelectScreen = _StringsServerSelectScreenFa._(_root); - @override late final _StringsSettingsScreenFa SettingsScreen = _StringsSettingsScreenFa._(_root); - @override late final _StringsSpeedTestSettingsScreenFa SpeedTestSettingsScreen = _StringsSpeedTestSettingsScreenFa._(_root); - @override late final _StringsTextToQrCodeScreenFa TextToQrCodeScreen = _StringsTextToQrCodeScreenFa._(_root); - @override late final _StringsUrlTestSettingsScreenFa UrlTestSettingsScreen = _StringsUrlTestSettingsScreenFa._(_root); - @override late final _StringsUserAgreementScreenFa UserAgreementScreen = _StringsUserAgreementScreenFa._(_root); - @override late final _StringsVersionUpdateScreenFa VersionUpdateScreen = _StringsVersionUpdateScreenFa._(_root); - @override late final _StringsCommonWidgetFa CommonWidget = _StringsCommonWidgetFa._(_root); - @override late final _StringsServerManagerFa ServerManager = _StringsServerManagerFa._(_root); - @override late final _StringsMainFa main = _StringsMainFa._(_root); - @override String get enable => 'فعال‌سازی'; - @override String get disable => 'غیرفعال'; - @override String get prefer => 'اولویت'; - @override String get only => 'فقط'; - @override String get open => 'باز کن'; - @override String get close => 'بسته'; - @override String get quit => 'خروج'; - @override String get add => 'افزودن'; - @override String get remove => 'حذف'; - @override String get edit => 'ویرایش کنید'; - @override String get view => 'بررسی'; - @override String get more => 'بیشتر'; - @override String get addProfile => 'افزودن پروفایل'; - @override String get addSuccess => 'با‌موفقیت اضافه شد'; - @override String addSuccessThen({required Object p}) => 'پیکربندی با موفقیت ایجاد شد، لطفاً برای مشاهده به [${p}] بروید'; - @override String addFailed({required Object p}) => 'افزودن ناموفق بود:${p}'; - @override String get removeConfirm => 'آیا از حذف اطمینان دارین؟'; - @override String get tips => 'اطلاعات'; - @override String get copy => 'کپی'; - @override String get ok => 'خُب'; - @override String get cancel => 'لغو'; - @override String get feedback => 'بازخورد'; - @override String get faq => 'سوالات متداول'; - @override String get download => 'دانلود'; - @override String get loading => 'درحال بارگذاری…'; - @override String updateFailed({required Object p}) => 'به‌روزرسانی ناموفق بود:${p}'; - @override String get days => 'روز'; - @override String get hours => 'ساعت'; - @override String get minutes => 'دقیقه'; - @override String get seconds => 'دومین'; - @override String get protocol => 'پروتکل'; - @override String get search => 'جستجو'; - @override String get custom => 'سفارشی'; - @override String get connect => 'اتصال'; - @override String get disconnect => 'قطع‌ اتصال'; - @override String get connected => 'وصل شد'; - @override String get disconnected => 'قطع شد'; - @override String get connecting => 'درحال اتصال'; - @override String get connectTimeout => 'اتمام مهلت اتصال'; - @override String get timeout => 'تایم اوت'; - @override String get language => 'زبان'; - @override String get next => 'بعدی'; - @override String get done => 'انجام‌شد'; - @override String get apply => 'درخواست دادن'; - @override String get refresh => 'بارگذاری مجدد'; - @override String get retry => 'دوباره امتحان کنید؟'; - @override String get none => 'هیچ‌کدام'; - @override String get reset => 'ریست'; - @override String get submit => 'ارسال'; - @override String get account => 'نام‌کاربری'; - @override String get password => 'رمز‌عبور'; - @override String get required => 'الزامی'; - @override String get diversion => 'انحراف'; - @override String get diversionRules => 'قوانین انحراف'; - @override String get diversionRulesEnable => 'قوانین بارگیری [ISP] را فعال کنید'; - @override String get diversionCustomGroup => 'گروه انحراف سفارشی'; - @override String get diversionCustomGroupPreset => 'از پیش تنظیم شده [گروه انحراف سفارشی]'; - @override String get diversionCustomGroupPresetTips => 'توجه: موارد فعال به [گروه انحراف سفارشی] و [قوانین انحراف] اضافه/پوشش داده خواهند شد'; - @override String get diversionCustomGroupAddTips => 'توجه: ممکن است لازم باشد پس از افزودن مرتب‌سازی به‌صورت دستی آن را تنظیم کنید، در غیر این صورت انحراف تازه اضافه‌شده ممکن است اعمال نشود.'; - @override String get urlTestCustomGroup => 'گروه پروکسی سفارشی'; - @override String get rulesetEnableTips => 'راهنمایی: پس‌از ذخیره کردن لطفا به [قوانین انحراف] رفته و قوانین مربوط زا تنظیم کنید؛ درغیراین صورت اعمال نخواهند شد'; - @override String get ispUserAgentTips => '[ISP] انواع مختلف داده های اشتراک را بر اساس [UserAgent] در درخواست [HTTP] ارائه خواهد کرد.'; - @override String get ispDiversionTips => 'قوانین بارگذاری ارائه شده توسط [ISP]، اشتراک های نوع [V2Ray] از قوانین تخلیه پشتیبانی نمی کنند'; - @override String get staticIP => 'IP استاتیک'; - @override String get other => 'دیگر'; - @override String get dns => 'DNS'; - @override String get url => 'URL'; - @override String get isp => 'ISP'; - @override String get tls => 'TLS'; - @override String get userAgent => 'UserAgent'; - @override String get urlInvalid => 'URL نامعتبر'; - @override String get outboundActionCurrentSelected => 'فعلی انتخاب شده'; - @override String get outboundActionUrltest => 'انتخاب خودکار'; - @override String get outboundActionDirect => 'مستقیم'; - @override String get outboundActionBlock => 'مسدود'; - @override String get routeFinal => 'نهایی'; - @override String get rulesetGeoSite => 'GeoSite'; - @override String get rulesetGeoIp => 'GeoIP'; - @override String get rulesetAcl => 'ACL'; - @override String get iCloud => 'iCloud'; - @override String get appleTV => 'Apple TV'; - @override String get webdav => 'Webdav'; - @override String get setting => 'تنظیمات'; - @override String get protocolSniff => 'تشخیص پروتکل'; - @override String get protocolSniffOverrideDestination => 'نام دامنه شناسایی شده آدرس هدف اتصال را پوشش می دهد'; - @override String get remark => 'ملاحضات'; - @override String get remarkCannotEmpty => 'ملاحظات نمی‌تواند خالی باشد'; - @override String get remarkTooLong => 'ملاحظات تا ۳۲ حرف'; - @override String get remarkExist => 'ملاحظات از‌قبل وجود دارد، لطفا از نام دیگری استفاده کنید'; - @override String get domainSuffix => 'پسوند دامنه'; - @override String get domain => 'دامنه'; - @override String get domainKeyword => 'کلید‌واژه دامنه'; - @override String get domainRegex => 'عبارات باقاعده ی دامنه (Regex)'; - @override String get ip => 'IP'; - @override String get port => 'پورت'; - @override String get appPackage => 'نام بسته‌ی برنامه'; - @override String get processName => 'نام اجرایی پروسه'; - @override String get processPath => 'مسیر پروسه'; - @override String get systemProxy => 'پروکسی سیستم'; - @override String get netInterfaces => 'رابط شبکه'; - @override String get netSpeed => 'سرعت'; - @override String get website => 'وبسایت'; - @override String get rule => 'قانون'; - @override String get global => 'عمومی'; - @override String get qrcode => 'کد QR'; - @override String get scanQrcode => 'اسکن QRکد'; - @override String get scanResult => 'نتایج اسکن'; - @override String get backupAndSync => 'پشتیبان‌گیری و همگام‌سازی'; - @override String get importAndExport => 'وارد‌کردن و خروجی‌گرفتن'; - @override String get import => 'وارد‌کردن'; - @override String get export => 'خروجی‌گرفتن'; - @override String get termOfUse => 'شرایط استفاده'; - @override String get privacyPolicy => 'سیاست حریم خصوصی'; - @override String get about => 'درباره'; - @override String get name => 'نام'; - @override String get version => 'نسخه'; - @override String get notice => 'اطلاعیه'; - @override String get sort => 'مرتب‌سازی'; - @override String get novice => 'حالت مبتدی'; - @override String get recommended => 'پیشنهادی'; - @override String innerError({required Object p}) => 'خطای داخلی: ${p}'; - @override String get logicOperation => 'عملیات منطقی'; - @override String get share => 'اشتراک گذاری'; - @override String get candidateWord => 'کلمات نامزد'; - @override String get keywordsOrRegx => 'کلمات کلیدی / معمولی'; - @override String get importFromClipboard => 'افزودن از کلیپ‌برد'; - @override String get exportToClipboard => 'صادرات به کلیپ بورد'; - @override String get server => 'سرور'; - @override String get appleTVConnectTurnOfprivateDirect => 'لطفاً ابتدا [اتصال مستقیم شبکه خصوصی] را فعال کنید'; - @override String targetConnectFailed({required Object p}) => 'اتصال به [${p}] ناموفق بود، لطفاً مطمئن شوید که دستگاه در همان LAN است و [اتصال مستقیم شبکه خصوصی] را فعال کنید.'; - @override String get appleTVSync => 'همگام سازی پیکربندی هسته فعلی با Apple TV - Karing'; - @override String get appleTVSyncDone => 'همگام سازی کامل شد، لطفاً برای باز کردن/راه اندازی مجدد اتصال به Apple TV - Karing بروید'; - @override String get appleTVRemoveCoreConfig => 'حذف Apple TV - Karing Core Configuration'; - @override String get appleTVRemoveCoreConfigDone => 'Apple TV - نمایه اصلی کارینگ حذف شد'; - @override String get appleTVUrlInvalid => 'URL نامعتبر است، لطفاً Apple TV - Karing را باز کنید، کد QR نمایش داده شده توسط Karing را اسکن کنید'; - @override String get remoteProfileEditConfirm => 'پس از به روز رسانی تنظیمات، تغییرات گره بازیابی می شوند آیا می خواهید ادامه دهید؟'; - @override String invalidFileType({required Object p}) => 'نوع فایل نامعتبر:${p}'; - @override Map get locales => { - 'en': 'English', - 'zh-CN': '简体中文', - 'ar': 'عربي', - 'ru': 'Русский', - 'fa': 'فارسی', - }; -} - -// Path: AboutScreen -class _StringsAboutScreenFa implements _StringsAboutScreenEn { - _StringsAboutScreenFa._(this._root); - - @override final _StringsFa _root; // ignore: unused_field - - // Translations - @override String get installRefer => 'مرجع نصب'; - @override String get versionChannel => 'کانال به‌روزرسانی خودکار'; - @override String get disableUAReport => 'خاموش کردن گزارش اطلاعات عملکرد'; - @override String get disableUAReportTip => 'گزارش‌دهی داده‌های رفتاری به ما کمک می‌کند تا نسخه‌های پایین‌تر از نسخه اصلی را بهبود بخشیم، همه گزارش‌های داده را به‌طور خودکار خاموش می‌کند (به‌جز [فعال‌سازی برنامه]).'; - @override String get devOptions => 'تنظیمات توسعه‌دهندگان'; - @override String get enableDebugLog => 'فعال‌سازی گزارش اشکال‌زدایی'; - @override String get viewFilsContent => 'مشاهده فایل‌ها'; - @override String get enablePprof => 'فعال‌سازی pprof'; - @override String get pprofPanel => 'پنل pprof'; - @override String get openDir => 'بازکردن دایرکتوری فایل'; - @override String get useOriginalSBProfile => 'استفاده از پروفایل اصلی سینگ‌باکس'; -} - -// Path: AddProfileByImportFromFileScreen -class _StringsAddProfileByImportFromFileScreenFa implements _StringsAddProfileByImportFromFileScreenEn { - _StringsAddProfileByImportFromFileScreenFa._(this._root); - - @override final _StringsFa _root; // ignore: unused_field - - // Translations - @override String get title => 'وارد‌کردن فایل پروفایل'; - @override String get chooseFile => 'انتخاب فایل'; - @override String get configExist => 'پروفایل از‌قبل وجود دارد، لطفا آن را به‌طور مکرر اضافه نکنید'; -} - -// Path: AddProfileByLinkOrContentScreen -class _StringsAddProfileByLinkOrContentScreenFa implements _StringsAddProfileByLinkOrContentScreenEn { - _StringsAddProfileByLinkOrContentScreenFa._(this._root); - - @override final _StringsFa _root; // ignore: unused_field - - // Translations - @override String get title => 'افزودن لینک پروفایل'; - @override String get updateTimerInterval => 'فاصله‌ی به‌روزرسانی'; - @override String get updateTimerIntervalTips => 'برای غیرفعال‌ کردن لطفا تنظیم کنید روی:<5m'; - @override String get profileLinkContent => 'لینک/محتوای پروفایل'; - @override String get profileLinkContentHit => 'لینک/محتوای پروفایل [الزامی] (پشتیبانی از کلش، V2ray(پشتیبانی به‌صورت دسته‌ای)، لینک‌های پروفایل فرعی)، استش، کارینگ، سینگ‌باکس، شدوساکس، لینک‌های پروفایل فرعی)'; - @override String get subscriptionCannotEmpty => 'لینک پروفایل نمی‌تواند خالی باشد'; - @override String get configExist => 'پروفایل از‌قبل وجود دارد، لطفا آن را به‌طور مکرر اضافه نکنید'; - @override String get invalidUrl => 'لینک پروفایل خیلی طولانی است'; - @override String addFailedFormatException({required Object p}) => 'فرمت اشتباه است، لطفا آن را اصلاح کرده و مجدد اضافه کنید:${p}'; - @override String addFailedThenDownloadAndImport({required Object p}) => 'افزودن نشد: ${p}، لطفاً [UserAgent] را تغییر دهید و دوباره امتحان کنید، یا از مرورگر خود دستگاه برای باز کردن پیوند پیکربندی و وارد کردن فایل پیکربندی دانلود شده توسط مرورگر به این برنامه استفاده کنید.'; - @override String addFailedHandshakeException({required Object p}) => 'اضافه کردن: ${p} ناموفق بود، لطفاً عامل را باز کنید یا گره عامل فعلی را تغییر دهید و دوباره امتحان کنید'; -} - -// Path: AddProfileByScanQrcodeScanScreen -class _StringsAddProfileByScanQrcodeScanScreenFa implements _StringsAddProfileByScanQrcodeScanScreenEn { - _StringsAddProfileByScanQrcodeScanScreenFa._(this._root); - - @override final _StringsFa _root; // ignore: unused_field - - // Translations - @override String get copy => 'کپی‌کردن لینک'; - @override String get open => 'بازکردن لینک'; - @override String get requestCameraPermission => 'لطفا مجوز دسترسی دوربین را فعال کنید'; - @override String get requestScreenAccess => 'لطفا به تنظیمات دستگاه - حریم‌خصوصی و امنیت - ظبط صفحه بروین تا مجوز‌های این نرم‌افزار را اضافه کنید'; - @override String get screenshot => 'اسکرین‌شات'; - @override String get scanFromImage => 'اسکن از عکس'; - @override String get scanNoResult => 'تجزیه عکس ناموفق بود، لطفا مطمعن شوید اسکرین‌شات یک کدQR معتبر است'; - @override String get scanEmptyResult => 'نتیجه اسکن خالی است'; - @override String scanException({required Object p}) => 'تجزیه عکس ناموفق بود، لطفا مطمعن شوید اسکرین‌شات یک کدQR معتبر است: ${p}'; -} - -// Path: BackupAndSyncLanSyncScreen -class _StringsBackupAndSyncLanSyncScreenFa implements _StringsBackupAndSyncLanSyncScreenEn { - _StringsBackupAndSyncLanSyncScreenFa._(this._root); - - @override final _StringsFa _root; // ignore: unused_field - - // Translations - @override String get title => 'LAN Sync'; - @override String get lanSyncNotQuitTips => 'قبل از تکمیل همگام‌سازی از این قسمت خارج نشوید'; -} - -// Path: BackupAndSyncWebdavScreen -class _StringsBackupAndSyncWebdavScreenFa implements _StringsBackupAndSyncWebdavScreenEn { - _StringsBackupAndSyncWebdavScreenFa._(this._root); - - @override final _StringsFa _root; // ignore: unused_field - - // Translations - @override String get webdavServerUrl => 'آدرس URL سرور'; - @override String get webdavRequired => 'نمی‌تواند خالی باشد'; - @override String get webdavLoginFailed => 'ورود ناموفق بود:'; - @override String get webdavListFailed => 'دریافت لیست فایل ناموفق بود:'; -} - -// Path: DiversionGroupCustomEditScreen -class _StringsDiversionGroupCustomEditScreenFa implements _StringsDiversionGroupCustomEditScreenEn { - _StringsDiversionGroupCustomEditScreenFa._(this._root); - - @override final _StringsFa _root; // ignore: unused_field - - // Translations - @override String invalidDomain({required Object p}) => 'نامعتبر [Domain]:${p}'; - @override String invalidIpCidr({required Object p}) => 'نامعتبر [IP Cidr]:${p}'; - @override String invalidPort({required Object p}) => 'نامعتبر [Port]:${p}'; - @override String invalidRuleSet({required Object p}) => 'نامعتبر [Rule Set]:${p} باید URL یک URL معتبر https باشد و یک فایل دودویی(binary) با پسوند فایل .srs/.json باشد'; - @override String invalidRuleSetBuildIn({required Object p}) => 'نامعتبر [Rule Set(build-in)]:${p} نامعتبر است، قالب geosite:xxx یا geoip:xxx یا acl:xxx است و xxx باید یک نام قانون معتبر باشد'; - @override String get setDiversionRule => 'راهنمایی: پس‌از ذخیره کردن لطفا به [قوانین انحراف] رفته و قوانین مربوط زا تنظیم کنید؛ درغیراین صورت اعمال نخواهند شد'; -} - -// Path: DiversionRuleDetectScreen -class _StringsDiversionRuleDetectScreenFa implements _StringsDiversionRuleDetectScreenEn { - _StringsDiversionRuleDetectScreenFa._(this._root); - - @override final _StringsFa _root; // ignore: unused_field - - // Translations - @override String get title => 'کشف قانون انحراف'; - @override String get detect => 'کشف'; - @override String get rule => 'قانون:'; - @override String get outbound => 'سرور پروکسی:'; -} - -// Path: DiversionRulesScreen -class _StringsDiversionRulesScreenFa implements _StringsDiversionRulesScreenEn { - _StringsDiversionRulesScreenFa._(this._root); - - @override final _StringsFa _root; // ignore: unused_field - - // Translations - @override String get diversionRulesMatchTips => 'نکته: سعی کنید قوانین را از بالا به پایین مطابقت دهید، از [نهایی] استفاده کنید.'; -} - -// Path: DnsSettingsScreen -class _StringsDnsSettingsScreenFa implements _StringsDnsSettingsScreenEn { - _StringsDnsSettingsScreenFa._(this._root); - - @override final _StringsFa _root; // ignore: unused_field - - // Translations - @override String get ispCanNotEmpty => 'ISP نمی‌تواند خالی باشد'; - @override String get urlCanNotEmpty => 'URL نمی‌تواند خالی باشد'; - @override String error({required Object p}) => 'نوع پشتیبانی نشده:${p}'; - @override String get dnsDesc => 'ستون اول داده‌های تأخیر، تأخیر ارتباط مستقیم است؛\nستون دوم: روشن کردن [[ترافیک پروکسی] برای حل و فصل DNS از طریق سرور پراکسی]: داده‌های تأخیر، تأخیر درخواست ارسال شده از طریق سرور پراکسی فعلی است [[ترافیک پروکسی] روشن نیست، از طریق سرور پروکسی DNS را حل می‌کند]: داده‌های تأخیر تأخیر درخواست اتصال مستقیم است'; -} - -// Path: FeedbackScreen -class _StringsFeedbackScreenFa implements _StringsFeedbackScreenEn { - _StringsFeedbackScreenFa._(this._root); - - @override final _StringsFa _root; // ignore: unused_field - - // Translations - @override String get content => 'محتوای بازخورد'; - @override String get contentHit => 'الزامی، تا 500 حرف'; - @override String get contentCannotEmpty => 'محتوای بازخورد نمی‌تواند خالی باشد'; -} - -// Path: FileContentViewerScreen -class _StringsFileContentViewerScreenFa implements _StringsFileContentViewerScreenEn { - _StringsFileContentViewerScreenFa._(this._root); - - @override final _StringsFa _root; // ignore: unused_field - - // Translations - @override String get title => 'نمایش دهنده محتوای فایل'; - @override String get chooseFile => 'انتخاب فایل'; - @override String get clearFileContent => 'آیا از پاکسازی محتوای فایل اطمینان دارید؟'; - @override String get clearFileContentTips => 'آیا از پاکسازی محتوای فایل پروفایل اطمینان دارید؟ پاکسازی محتوای فایل پروفایل ممکن است باعث از دست رفتن داده یا عملیات غیرعادی نرم‌افزار شود؛ لطفا با احتیاط عمل کنید.'; -} - -// Path: HomeScreen -class _StringsHomeScreenFa implements _StringsHomeScreenEn { - _StringsHomeScreenFa._(this._root); - - @override final _StringsFa _root; // ignore: unused_field - - // Translations - @override String get toSelectServer => 'لطفا یک سرور انتخاب کنید'; - @override String get invalidServer => 'نامعتبر است، لطفا مجدد انتخاب کنید'; - @override String get disabledServer => 'غیرفعال است، لطفا مجدد انتخاب کنید'; - @override String get expiredServer => 'هیچ سروری در دسترس نیست: ممکن است پیکربندی قدیمی یا غیرفعال باشد'; - @override String systemProxyTips({required Object sp, required Object hp}) => 'socks:${sp},http(s):${hp}'; - @override String get trafficTotal => 'کل ترافیک'; - @override String get trafficProxy => 'ترافیک پروکسی'; - @override String get myLinkEmpty => 'لطفا قبل‌از استفاده [لینک میان‌بر] را راه‌اندازی کنید'; - @override String get deviceNoSpace => 'فضای خالی کافی ندارید'; - @override String tooMuchServers({required Object p, required Object p1}) => 'تعداد زیادی سرور پروکسی [${p}>${p1}] وجود دارد و ممکن است به دلیل محدودیت حافظه سیستم، اتصال امکان پذیر نباشد.'; -} - -// Path: LaunchFailedScreen -class _StringsLaunchFailedScreenFa implements _StringsLaunchFailedScreenEn { - _StringsLaunchFailedScreenFa._(this._root); - - @override final _StringsFa _root; // ignore: unused_field - - // Translations - @override String get invalidProcess => 'اجرای نرم‌افزار ناموفق بود [نام‌ اجرایی پروسه نامعتبر]، لطفا مجدد نرم‌افزار را در دایرکتوری دیگری نصب کنید'; - @override String get invalidProfile => 'اجرای نرم‌افزار ناموفق بود [دسترسی به پروفایل ناموفق بود]، لطفا مجدد نرم افزار را نصب کنید'; - @override String get invalidVersion => 'اجرای نرم‌افزار ناموفق بود [ورژن نامعتبر]، لطفا مجدد نرم‌افزار را نصب کنید'; - @override String get systemVersionLow => 'راه اندازی برنامه ناموفق بود [نسخه سیستم خیلی کم است]'; - @override String get startFromUNC => 'مسیر نصب نامعتبر است، لطفا مجدد در مسیر معتبر نصب کنید'; -} - -// Path: MyProfilesEditScreen -class _StringsMyProfilesEditScreenFa implements _StringsMyProfilesEditScreenEn { - _StringsMyProfilesEditScreenFa._(this._root); - - @override final _StringsFa _root; // ignore: unused_field - - // Translations - @override String get title => 'ویرایش پروفایل'; - @override String get urlExist => 'آدرس URL از‌قبل وجود دارد، لطفا از URL دیگری استفاده کنید'; - @override String get updateTimerInterval => 'فاصله‌ی به‌روزرسانی'; - @override String get updateTimerIntervalTips => 'برای غیرفعال‌ کردن لطفا تنظیم کنید روی:<5m'; - @override String get reloadAfterProfileUpdate => 'بارگذاری مجدد پس‌از به‌روزرسانی پروفایل'; - @override String get testLatencyAfterProfileUpdate => 'شروع تست تاخیر پس‌از به‌روزرسانی خودکار پروفایل'; - @override String get testLatencyAfterProfileUpdateTips => 'وی‌پی‌ان باید روشن و [بارگذاری مجدد پس‌از به‌روزرسانی پروفایل] فعال باشد'; - @override String get testLatencyAutoRemove => 'خودکار سرورهای ناموفق در تست تاخیر را حذف کن'; - @override String get testLatencyAutoRemoveTips => 'تا سه بار امتحان کنید'; -} - -// Path: MyProfilesMergeScreen -class _StringsMyProfilesMergeScreenFa implements _StringsMyProfilesMergeScreenEn { - _StringsMyProfilesMergeScreenFa._(this._root); - - @override final _StringsFa _root; // ignore: unused_field - - // Translations - @override String get profilesMerge => 'ادغام پروفایل‌ها'; - @override String get profilesMergeTarget => 'پروفایل هدف'; - @override String get profilesMergeSource => 'پروفایل مرجع'; - @override String get profilesMergeTips => 'راهنمایی: انحراف پروفایل مرجع حذف می‌شود'; -} - -// Path: MyProfilesScreen -class _StringsMyProfilesScreenFa implements _StringsMyProfilesScreenEn { - _StringsMyProfilesScreenFa._(this._root); - - @override final _StringsFa _root; // ignore: unused_field - - // Translations - @override String get title => 'پروفایل‌ها'; - @override String get atLeastOneEnable => 'نمی‌تواند غیرغعال شود، لطفا حداقل یک پروفایل را فعال نگه دارید'; -} - -// Path: NetCheckScreen -class _StringsNetCheckScreenFa implements _StringsNetCheckScreenEn { - _StringsNetCheckScreenFa._(this._root); - - @override final _StringsFa _root; // ignore: unused_field - - // Translations - @override String get title => 'بررسی شبکه'; - @override String get warn => 'توجه: به دلیل تأثیر محیط شبکه و قوانین انحراف، نتایج آزمون کاملاً معادل نتایج واقعی نیست.'; - @override String get check => 'بررسی'; - @override String get invalidDomain => 'نام دامنه نامعتبر'; - @override String get connectivity => 'اتصال شبکه'; - @override String connectivityTestIpv4AllFailed({required Object p}) => 'تست اتصال Ipv4 همه‌ی [${p}] ناموفق بودند'; - @override String get connectivityTestIpv4Ok => 'اتصال Ipv4 موفق بود'; - @override String connectivityTestIpv6AllFailed({required Object p}) => 'تست اتصال Ipv6 همه‌ی [${p}] ناموفق بودند، شاید شبکه شما از Ipv6 پشتیبانی نکند'; - @override String get connectivityTestIpv6Ok => 'اتصال Ipv6 موفق بود'; - @override String get connectivityTestOk => 'شبکه به اینترنت متصل است'; - @override String get connectivityTestFailed => 'شبکه هنوز به اینترنت متصل نشده'; - @override String get remoteRulesetsDownloadOk => 'همه با موفقیت دانلود شدند'; - @override String get remoteRulesetsDownloadNotOk => 'دانلود شد یا ناموفق بود'; - @override String get outbound => 'سرور پروکسی'; - @override String outboundOk({required Object p}) => '[${p}] اتصال موفق بود'; - @override String outboundFailed({required Object p1, required Object p2}) => '[${p1}] اتصال ناموفق \nارور:[${p2}]'; - @override String get dnsServer => 'سرور دی‌ان‌اس'; - @override String dnsOk({required Object p1, required Object p2, required Object p3, required Object p4}) => '[${p1}]DNS query succeeded\nDNS Rule: درخواست دی‌ان‌اس موفق بود\nقانون دی‌ان‌اس: [${p2}]\nتاخیر: [${p3} ms]\nآدرس [${p4}]'; - @override String dnsFailed({required Object p1, required Object p2, required Object p3}) => '[${p1}]جستجوی DNS موفق بود\nقانون DNS: [${p2}]\nخطا:[${p3}]'; - @override String get host => 'اتصال HTTP'; - @override String hostConnection({required Object p1, required Object p2, required Object p3}) => '[${p1}]\nقانون انحراف: [${p2}]\nسرور پروکسی: [${p3}]'; - @override String get hostConnectionOk => 'اتصال موفق شد'; - @override String hostConnectionFailed({required Object p}) => 'ارتباط ناموفق بود:[${p}]'; -} - -// Path: NetConnectionsFilterScreen -class _StringsNetConnectionsFilterScreenFa implements _StringsNetConnectionsFilterScreenEn { - _StringsNetConnectionsFilterScreenFa._(this._root); - - @override final _StringsFa _root; // ignore: unused_field - - // Translations - @override String get title => 'فیلتر اتصال‌ها'; - @override String get hostIp => 'دامنه/آی‌پی'; - @override String get app => 'نرم‌افزار'; - @override String get rule => 'قانون'; - @override String get chain => 'Outbound'; -} - -// Path: NetConnectionsScreen -class _StringsNetConnectionsScreenFa implements _StringsNetConnectionsScreenEn { - _StringsNetConnectionsScreenFa._(this._root); - - @override final _StringsFa _root; // ignore: unused_field - - // Translations - @override String get title => 'اتصال‌ها'; - @override String get copyAsCSV => 'در فرمت CAV کپی شد'; - @override String get selectType => 'انتخاب نوع انحراف'; -} - -// Path: PerAppAndroidScreen -class _StringsPerAppAndroidScreenFa implements _StringsPerAppAndroidScreenEn { - _StringsPerAppAndroidScreenFa._(this._root); - - @override final _StringsFa _root; // ignore: unused_field - - // Translations - @override String get title => 'پروکسی به‌تفکیک برنامه'; - @override String get whiteListMode => 'حالت لیست سفید'; - @override String get whiteListModeTip => 'وقتی فعال باشد: فقط برنامه‌هایی که انتخاب شده‌اند پروکسی می‌شوند؛ وقتی فعال نباشد: فقط برنامه‌هایی که انتخاب نشده‌اند پروکسی می‌شوند'; - @override String get hideSystemApp => 'برنامه های سیستم را مخفی کنید'; - @override String get hideAppIcon => 'پنهان کردن نماد برنامه'; - @override String get enableAppQueryPermission => 'مجوز [درخواست لیست نرم‌افزار] را روشن کنید'; -} - -// Path: QrcodeScreen -class _StringsQrcodeScreenFa implements _StringsQrcodeScreenEn { - _StringsQrcodeScreenFa._(this._root); - - @override final _StringsFa _root; // ignore: unused_field - - // Translations - @override String get tooLong => 'متن برای نمایش خیلی طولانی است'; - @override String get copy => 'کپی‌کردن لینک'; - @override String get open => 'بازکردن لینک'; - @override String get share => 'اشتراک لینک'; - @override String get shareImage => 'اشتراک کدQR'; -} - -// Path: RegionSettingsScreen -class _StringsRegionSettingsScreenFa implements _StringsRegionSettingsScreenEn { - _StringsRegionSettingsScreenFa._(this._root); - - @override final _StringsFa _root; // ignore: unused_field - - // Translations - @override String get title => 'کشور یا منطقه'; - @override String get Regions => 'راهنمایی: لطفا کشور یا منطقه فعلی خود را انتخاب کنید درغیراین‌صورت ممکن‌است باعث مشکلات انحراف شبکه شود'; -} - -// Path: ServerSelectScreen -class _StringsServerSelectScreenFa implements _StringsServerSelectScreenEn { - _StringsServerSelectScreenFa._(this._root); - - @override final _StringsFa _root; // ignore: unused_field - - // Translations - @override String get title => 'انتخاب سرور'; - @override String get autoSelectServer => 'خودکار سرور با کمترین تاخیر را انتخاب کن'; - @override String get recentUse => 'اخیرا استفاده‌شده'; - @override String get myFav => 'علاقه‌مندی‌های من'; - @override String selectLocal({required Object p}) => 'سرور انتخاب شده یک آدرس محلی است و شاید به درستی عمل نکند :${p}'; - @override String get selectRequireEnableIPv6 => 'سرور انتخاب شده یک آدرس IPv6 است و نیاز به [فعال‌سازی IPv6] دارد'; - @override String get selectDisabled => 'این سرور غیرفعال شده است'; - @override String get error404 => 'تشخیص تاخیر با یک اخطار مواجه شده‌است، لطفا بررسی کنید که کانفیگی با محتویات یکسان وجود دارد یا خیر'; -} - -// Path: SettingsScreen -class _StringsSettingsScreenFa implements _StringsSettingsScreenEn { - _StringsSettingsScreenFa._(this._root); - - @override final _StringsFa _root; // ignore: unused_field - - // Translations - @override String ispFaq({required Object p}) => 'سوالات متداول[${p}]'; - @override String cleanISP({required Object p}) => 'پاک‌سازی ISP [${p}]'; - @override String get openISP => 'بازکردن لینک ISP'; - @override String get cleanISPNoParam => 'پاک‌سازی اطلاعات ISP'; - @override String get getTranffic => 'دریافت ترافیک'; - @override String get tutorial => 'آموزش'; - @override String get commonlyUsedRulesets => 'قوانین رایج'; - @override String get howToRemoveAds => 'نحوه حذف تبلیغات'; - @override String get htmlBoard => 'پنل آنلاین'; - @override String get dnsLeakDetection => 'تشخیص نشت DNS'; - @override String get speedTest => 'تست سرعت'; - @override String get downloadProfilePreferProxy => 'برای دانلود پروفایل پروکسی را ترجیح بده'; - @override String get downloadProfilePreferProxyTips => 'اگر اکنون متصل هستین، پروفایل ابتدا از پروکسی متصل دانلود می‌شود'; - @override String get rulesetDirectDownlad => 'دانلود مستقیم مجموعه قوانین'; - @override String get hideUnusedDiversionGroup => 'مخفی‌کردن گروه‌های انحراف به‌کار نرفته'; - @override String get disableISPDiversionGroup => 'قوانین انحراف ISP را غیرفعال کنید'; - @override String get portSetting => 'پورت'; - @override String get portSettingRule => 'قانون محور'; - @override String get portSettingDirectAll => 'مستقیم‌شدن همه'; - @override String get portSettingProxyAll => 'پروکسی‌شدن همه'; - @override String get portSettingControl => 'کنترل و همگام‌سازی'; - @override String get portSettingCluster => 'سرویس کلاستر'; - @override String get modifyPort => 'اصلاح پورت'; - @override String get ipStrategyTips => 'قبل‌از فعال‌سازی لطفا مطمعن شوید شبکه شما از IPv6 پشتیبانی می‌کند، وگرنه برخی ترافیک‌ها نمی‌توانند به‌صورت نرمال دردسترس باشند'; - @override String get tunAppendHttpProxy => 'پیوست دادن پروکسی HTTP به وی‌پی‌ان'; - @override String get tunAppendHttpProxyTips => 'برخی نرم‌افزار‌ها از کارت شبکه مجازی رد میشوند و مستقیم به پروکسی HTTP متصل می‌شوند'; - @override String get tlsInsecureEnable => 'رد شدن از تأیید گواهی'; - @override String get tlsFragmentEnable => 'بخش بندی TLS را فعال کنید'; - @override String get tlsFragmentSize => 'اندازه بخش TLS'; - @override String get tlsFragmentSleep => 'خواب بخش‌بندی شده TLS'; - @override String get tlsMixedCaseSNIEnable => 'TLS ترکیبی SNI را فعال کنید'; - @override String get tlsPaddingEnable => 'فعال کردن TLS Padding'; - @override String get tlsPaddingSize => 'اندازه پد TLS'; - @override String get dnsEnableRule => 'فعال‌سازی قوانین انحراف دی‌ان‌اس'; - @override String get dnsEnableFakeIp => 'فعال‌سازی آی‌پی جعلی'; - @override String get dnsEnableClientSubnet => 'ECS را فعال کنید'; - @override String get dnsEnableProxyResolveByProxy => 'دی‌ان‌اس را از [ترافیک پروکسی] سرور پروکسی عبور می‌دهد'; - @override String get dnsEnableFinalResolveByProxy => 'دی‌ان‌اس را از سرور پروکسی [نهایی] عبور می‌دهد'; - @override String get dnsTestDomain => 'تست دامنه'; - @override String get dnsTestDomainInvalid => 'دامنه نامعتبر'; - @override String get dnsTypeOutbound => 'سرور پروکسی'; - @override String get dnsTypeDirect => 'ترافیک مستقیم'; - @override String get dnsTypeProxy => 'ترافیک پروکسی'; - @override String get dnsTypeResolver => 'سرور دی‌ان‌اس'; - @override String get dnsEnableRuleTips => 'بعد از فعال‌سازی نام دامنه، سرور دی‌ان‌اس مربوط را بر اساس قوانین انحراف برای عبور انتخاب می‌کند'; - @override String get dnsEnableFakeIpTips => 'پس از فعال کردن FakeIP، اگر اتصال VPN قطع شود، ممکن است برنامه شما نیاز به راه اندازی مجدد داشته باشد [حالت TUN].'; - @override String get dnsTypeOutboundTips => 'سامانه نام دامنه (DNS) برای سرور پروکسی'; - @override String get dnsTypeDirectTips => 'سامانه نام دامنه (DNS) برای ترافیک مستقیم'; - @override String get dnsTypeProxyTips => 'سامانه نام دامنه (DNS) برای ترافیک پروکسی'; - @override String get dnsTypeResolverTips => 'سامانه نام دامنه (DNS) برای بقیه سرور دی‌ان‌اس'; - @override String get dnsTypeFinalTips => 'سامانه نام دامنه (DNS) برای بقیه ترافیک'; - @override String get dnsAutoSetServer => 'به طور خودکار سرور را راه اندازی کنید'; - @override String get dnsResetServer => 'بازنشانی سرور'; - @override String get inboundDomainResolve => 'حل نام دامنه های ورودی'; - @override String get privateDirect => 'اتصال مستقیم شبکه خصوصی'; - @override String inboundDomainResolveTips({required Object p}) => 'برخی از نام‌های دامنه بدون قوانین انحراف پیکربندی شده باید حل و فصل شوند تا بتوانند قوانین انحراف مبتنی بر IP را تحت تأثیر قرار دهند [${p}].'; - @override String get useRomoteRes => 'از منابع راه‌دور استفاده کنید'; - @override String get autoSelect => 'انتخاب خودکار'; - @override String get autoSelectServerIgnorePerProxyServer => 'سرور پروکسی [پراکسی جلو] را نادیده بگیرید'; - @override String get autoSelectServerInterval => 'بازه زمانی بررسی تاخیر'; - @override String get autoSelectServerReTestIfNetworkUpdate => 'شناسایی مجدد زمانی که شبکه تغییر می کند'; - @override String get autoSelectServerUpdateCurrentServerAfterManualUrltest => 'سرور فعلی را پس از تشخیص تأخیر دستی به روز کنید'; - @override String get autoSelectServerIntervalTips => 'هرچه فاصله تشخیص تاخیر کمتر باشد، داده های تاخیر سرور به موقع به روز می شود، اما منابع بیشتری را اشغال می کند و برق را سریعتر مصرف می کند'; - @override String get autoSelectServerFavFirst => 'اولویت استفاده از [علاقه‌مندی‌های من]'; - @override String get autoSelectServerFavFirstTips => 'اگر لیست [علاقه‌مندی‌های من] خالی نبود از سرور‌های داخل [علاقه‌مندی‌های من] استفاده کن'; - @override String get autoSelectServerFilter => 'فیلترکردن سرور‌های نامعتبر'; - @override String autoSelectServerFilterTips({required Object p}) => 'اگر بعد از فیلتر کردن هیچ سروری در دسترس نباشد، از اولین سرورهای [${p}] استفاده خواهد شد.'; - @override String get autoSelectServerLimitedNum => 'حداکثر تعداد سرور'; - @override String get autoSelectServerLimitedNumTips => 'سرورهای بیش از این تعداد فیلتر خواهند شد'; - @override String get numInvalid => 'عدد نامعتبر'; - @override String get hideInvalidServer => 'مخفی‌کردن سرور‌های نامعتبر'; - @override String get sortServer => 'مرتب‌سازی سرور'; - @override String get sortServerTips => 'مرتب‌سازی براساس تاخیر از کم به زیاد'; - @override String get selectServerHideRecommand => 'مخفی‌کردن [پیشنهادی]'; - @override String get selectServerHideRecent => '‌ مخفی‌کردن [اخیرا استفاده‌شده]'; - @override String get selectServerHideFav => 'مخفی‌کردن [علاقه‌مندی‌های من]'; - @override String get homeScreen => 'صفحه‌ خانه'; - @override String get theme => 'تِم'; - @override String get myLink => 'لینک میان‌بر'; - @override String get myLinkInvalid => 'URL نامعتبر'; - @override String get autoConnectAfterLaunch => 'اتصال خودکار پس‌از راه‌اندازی'; - @override String get hideAfterLaunch => 'پنهان کردن پنجره پس از راه اندازی'; - @override String get autoSetSystemProxy => 'تنظیم خودکار حالت پروکسی سیستم پس‌از اتصال'; - @override String get disconnectWhenQuit => 'قطع اتصال هنگام خروج از نرم‌افزار'; - @override String get allowBypass => 'به برنامه‌ها اجازه دهید VPN را دور بزنند'; - @override String get lanSyncTo => 'همگام‌سازی با دیگران'; - @override String get lanSyncFrom => 'همگام‌سازی از دیگران'; - @override String get lanSyncScanQRcode => 'اسکن کدQR و همگام‌سازی'; - @override String get syncToConfirm => 'همگام سازی را با طرف مقابل تأیید می کنید؟'; - @override String get syncDone => 'همگام سازی تکمیل شد'; - @override String get importSuccess => 'افزودن موفق بود'; - @override String get rewriteConfirm => 'این فایل کانفیگ‌های محلی موجود را بازنویسی می‌کند. آیا می‌خواهید ادامه بدین؟'; - @override String get networkShare => 'اشتراک‌گذاری شبکه'; - @override String get frontProxy => 'پروکسی جلو'; - @override String get frontProxyTips => 'داده‌ها->سرور پروکسی جلو->سرور پروکسی->سرور هدف'; - @override String get allowOtherHostsConnect => 'اجازه اتصال دیگران'; - @override String allowOtherHostsConnectTips({required Object sp, required Object hp}) => 'socks:${sp},http(s):${hp}'; - @override String get tunAutoRoute => 'Auto Route'; - @override String get tunStrictRoute => 'Strict Route'; - @override String get tunStrictRouteTips => 'اگر پس از روشن کردن اشتراک‌گذاری، دیگران نمی‌توانند به این دستگاه دسترسی داشته باشند، لطفاً این سوئیچ را خاموش کنید.'; - @override String get enableCluster => 'فعال‌سازی پروکسی Socks/Http خوشه‌ای'; - @override String get clusterAllowOtherHostsConnect => 'اجازه اتصال دیگران به خوشه'; - @override String clusterAllowOtherHostsConnectTips({required Object hp}) => 'http://127.0.0.1:${hp}/get_proxies'; - @override String get clusterAuth => 'احراز هویت خوشه پروکسی'; - @override String get clusterConfirm => 'لطفا مطمعن شوید تاخیر سرورها بررسی شده و درصورتی‌که بررسی نشده‌باشند یا اشتباه بررسی شده‌باشند سرویس پروکسی ساخته نمی‌شود'; - @override String get tunMode => 'حالت TUN'; - @override String get tunModeTips => 'حالت TUN تمام ترافیک سیستم را تحت کنترل خواهد گرفت [دراین حالت می‌توانید پروکسی سیستم را غیرفعال نگه‌ دارید)'; - @override String get tunModeRunAsAdmin => 'حالت TUN نیازمند مجوز مدیر سیستم می‌باشد لطفا نرم‌افزار را مجدد با حالت مدیر (administrator) راه‌اندازی کنید'; - @override String get tunStack => 'Stack'; - @override String get launchAtStartup => 'اجرا در راه‌اندازی'; - @override String get quitWhenSwitchSystemUser => 'خروج از نرم‌افزار هنگام تعویض کاربران سیستم'; - @override String get handleScheme => 'فراخوانی Scheme سیستم'; - @override String get portableMode => 'حالت قابل‌حمل'; - @override String get portableModeDisableTips => 'اگر نیاز دارین از حالت قابل‌حمل خارج شوید لطفا از [Karing] خارج شده و به‌صورت دستی پوشه [Profiles] هم مسیر با فایل [karing.exe] را حذف کنید'; - @override String get handleKaringScheme => 'رسیدگی به ندای karing://'; - @override String get handleClashScheme => 'رسیدگی به‌ ندای clash://'; - @override String get handleSingboxScheme => 'رسیدگی به ندای sing-box://'; - @override String get removeSystemVPNConfig => 'حذف پیکربندی وی‌پی‌ان سیستم'; - @override String get timeConnectOrDisconnect => 'اتصال/قطع اتصال برنامه‌ریزی شده'; - @override String get timeConnectOrDisconnectTips => 'برای اعمال شدن وی‌پی‌ان باید متصل باشد. پس‌از روشن‌شدن [خواب خودکار] غیرفعال می‌شود'; - @override String timeConnectAndDisconnectInterval({required Object p}) => 'The connection/disconnection interval cannot be less than ${p} minutes'; - @override String get disableFontScaler => 'غیرفعال‌سازی مقیاس‌بندی فونت(با راه‌اندازی مجدد اعمال می‌شود)'; - @override String get autoOrientation => 'چرخش صفحه را دنبال کنید'; - @override String get restartTakesEffect => 'با راه‌اندازی مجدد اعمال می‌شود'; - @override String get resetSettings => 'بازنشانی تنظیمات'; - @override String get cleanCache => 'پاک کردن حافظه پنهان'; - @override String get cleanCacheDone => 'پاکسازی کامل شد'; - @override String get appleTestFlight => 'تست‌فلایت اپل'; - @override String get appleAppStore => 'اپ‌استور اپل'; - @override String hasNewVersion({required Object p}) => 'به‌روزرسانی نسخه ${p} '; - @override String get follow => 'مارو دنبال کنید'; - @override String get contactUs => 'ارتباط باما'; - @override String get rateInApp => 'امتیاز به ما'; - @override String get rateInAppStore => 'به ما در اپ‌استور امتیاز بدین'; -} - -// Path: SpeedTestSettingsScreen -class _StringsSpeedTestSettingsScreenFa implements _StringsSpeedTestSettingsScreenEn { - _StringsSpeedTestSettingsScreenFa._(this._root); - - @override final _StringsFa _root; // ignore: unused_field - - // Translations - @override String get title => 'URL تست سرعت'; - @override String get error => 'باید یک URL معتبر https باشد'; -} - -// Path: TextToQrCodeScreen -class _StringsTextToQrCodeScreenFa implements _StringsTextToQrCodeScreenEn { - _StringsTextToQrCodeScreenFa._(this._root); - - @override final _StringsFa _root; // ignore: unused_field - - // Translations - @override String get title => 'متن به کد QR'; - @override String get convert => 'تبدیل'; -} - -// Path: UrlTestSettingsScreen -class _StringsUrlTestSettingsScreenFa implements _StringsUrlTestSettingsScreenEn { - _StringsUrlTestSettingsScreenFa._(this._root); - - @override final _StringsFa _root; // ignore: unused_field - - // Translations - @override String get title => 'URL بررسی تاخیر'; - @override String get error => 'باید یک URL معتبر https باشد'; -} - -// Path: UserAgreementScreen -class _StringsUserAgreementScreenFa implements _StringsUserAgreementScreenEn { - _StringsUserAgreementScreenFa._(this._root); - - @override final _StringsFa _root; // ignore: unused_field - - // Translations - @override String get privacyFirst => 'حریم‌خصوصی شما اولویت دارد'; - @override String get agreeAndContinue => 'پذیرفتن و ادامه'; -} - -// Path: VersionUpdateScreen -class _StringsVersionUpdateScreenFa implements _StringsVersionUpdateScreenEn { - _StringsVersionUpdateScreenFa._(this._root); - - @override final _StringsFa _root; // ignore: unused_field - - // Translations - @override String versionReady({required Object p}) => 'نسخه جدید [${p}] آماده است'; - @override String get update => 'راه‌اندازی مجدد برای به‌روزرسانی'; - @override String get cancel => 'الان‌ نه'; -} - -// Path: CommonWidget -class _StringsCommonWidgetFa implements _StringsCommonWidgetEn { - _StringsCommonWidgetFa._(this._root); - - @override final _StringsFa _root; // ignore: unused_field - - // Translations - @override String get diableAlwayOnVPN => 'اگر [وی‌پی‌ان همیشه روشن] روشن است لطفا [وی‌پی‌ان همیشه روشن] را خاموش کنید و مجدد برای اتصال تلاش کنید'; - @override String get resetPort => 'لطفاً پورت را به پورت موجود دیگری تغییر دهید یا برنامه ای را که پورت را اشغال می کند ببندید.'; -} - -// Path: ServerManager -class _StringsServerManagerFa implements _StringsServerManagerEn { - _StringsServerManagerFa._(this._root); - - @override final _StringsFa _root; // ignore: unused_field - - // Translations - @override String get noServerAvaliable => 'هیچ سروری در دسترس نیست، لطفاً مطمئن شوید که پیوند پیکربندی یا فایل پیکربندی معتبر است، اگر پیکربندی شما از GitHub آمده است، لطفاً آدرس پیوند را از دکمه [Raw] در صفحه دریافت کنید'; - @override String get filePathCannotEmpty => 'مسیر فایل نمی‌تواند خالی باشد'; - @override String fileNotExist({required Object p}) => 'فایل وجود ندارد:${p}'; - @override String get urlCannotEmpty => 'لینک نمی‌تواند خالی باشد'; - @override String get invalidUrl => 'لینک پروفایل نامعتبر است'; - @override String get parseFailed => 'تجزیه پروفایل انجام نشد'; -} - -// Path: main -class _StringsMainFa implements _StringsMainEn { - _StringsMainFa._(this._root); - - @override final _StringsFa _root; // ignore: unused_field - - // Translations - @override late final _StringsMainTrayFa tray = _StringsMainTrayFa._(_root); -} - -// Path: main.tray -class _StringsMainTrayFa implements _StringsMainTrayEn { - _StringsMainTrayFa._(this._root); - - @override final _StringsFa _root; // ignore: unused_field - - // Translations - @override String get menuOpen => ' بازکردن '; - @override String get menuExit => ' بستن '; -} - -// Path: -class _StringsRu implements Translations { - /// You can call this constructor and build your own translation instance of this locale. - /// Constructing via the enum [AppLocale.build] is preferred. - _StringsRu.build({Map? overrides, PluralResolver? cardinalResolver, PluralResolver? ordinalResolver}) - : assert(overrides == null, 'Set "translation_overrides: true" in order to enable this feature.'), - $meta = TranslationMetadata( - locale: AppLocale.ru, - overrides: overrides ?? {}, - cardinalResolver: cardinalResolver, - ordinalResolver: ordinalResolver, - ) { - $meta.setFlatMapFunction(_flatMapFunction); - } - - /// Metadata for the translations of . - @override final TranslationMetadata $meta; - - /// Access flat map - @override dynamic operator[](String key) => $meta.getTranslation(key); - - @override late final _StringsRu _root = this; // ignore: unused_field - - // Translations - @override late final _StringsAboutScreenRu AboutScreen = _StringsAboutScreenRu._(_root); - @override late final _StringsAddProfileByImportFromFileScreenRu AddProfileByImportFromFileScreen = _StringsAddProfileByImportFromFileScreenRu._(_root); - @override late final _StringsAddProfileByLinkOrContentScreenRu AddProfileByLinkOrContentScreen = _StringsAddProfileByLinkOrContentScreenRu._(_root); - @override late final _StringsAddProfileByScanQrcodeScanScreenRu AddProfileByScanQrcodeScanScreen = _StringsAddProfileByScanQrcodeScanScreenRu._(_root); - @override late final _StringsBackupAndSyncLanSyncScreenRu BackupAndSyncLanSyncScreen = _StringsBackupAndSyncLanSyncScreenRu._(_root); - @override late final _StringsBackupAndSyncWebdavScreenRu BackupAndSyncWebdavScreen = _StringsBackupAndSyncWebdavScreenRu._(_root); - @override late final _StringsDiversionGroupCustomEditScreenRu DiversionGroupCustomEditScreen = _StringsDiversionGroupCustomEditScreenRu._(_root); - @override late final _StringsDiversionRuleDetectScreenRu DiversionRuleDetectScreen = _StringsDiversionRuleDetectScreenRu._(_root); - @override late final _StringsDiversionRulesScreenRu DiversionRulesScreen = _StringsDiversionRulesScreenRu._(_root); - @override late final _StringsDnsSettingsScreenRu DnsSettingsScreen = _StringsDnsSettingsScreenRu._(_root); - @override late final _StringsFeedbackScreenRu FeedbackScreen = _StringsFeedbackScreenRu._(_root); - @override late final _StringsFileContentViewerScreenRu FileContentViewerScreen = _StringsFileContentViewerScreenRu._(_root); - @override late final _StringsHomeScreenRu HomeScreen = _StringsHomeScreenRu._(_root); - @override late final _StringsLaunchFailedScreenRu LaunchFailedScreen = _StringsLaunchFailedScreenRu._(_root); - @override late final _StringsMyProfilesEditScreenRu MyProfilesEditScreen = _StringsMyProfilesEditScreenRu._(_root); - @override late final _StringsMyProfilesMergeScreenRu MyProfilesMergeScreen = _StringsMyProfilesMergeScreenRu._(_root); - @override late final _StringsMyProfilesScreenRu MyProfilesScreen = _StringsMyProfilesScreenRu._(_root); - @override late final _StringsNetCheckScreenRu NetCheckScreen = _StringsNetCheckScreenRu._(_root); - @override late final _StringsNetConnectionsFilterScreenRu NetConnectionsFilterScreen = _StringsNetConnectionsFilterScreenRu._(_root); - @override late final _StringsNetConnectionsScreenRu NetConnectionsScreen = _StringsNetConnectionsScreenRu._(_root); - @override late final _StringsPerAppAndroidScreenRu PerAppAndroidScreen = _StringsPerAppAndroidScreenRu._(_root); - @override late final _StringsQrcodeScreenRu QrcodeScreen = _StringsQrcodeScreenRu._(_root); - @override late final _StringsRegionSettingsScreenRu RegionSettingsScreen = _StringsRegionSettingsScreenRu._(_root); - @override late final _StringsServerSelectScreenRu ServerSelectScreen = _StringsServerSelectScreenRu._(_root); - @override late final _StringsSettingsScreenRu SettingsScreen = _StringsSettingsScreenRu._(_root); - @override late final _StringsSpeedTestSettingsScreenRu SpeedTestSettingsScreen = _StringsSpeedTestSettingsScreenRu._(_root); - @override late final _StringsTextToQrCodeScreenRu TextToQrCodeScreen = _StringsTextToQrCodeScreenRu._(_root); - @override late final _StringsUrlTestSettingsScreenRu UrlTestSettingsScreen = _StringsUrlTestSettingsScreenRu._(_root); - @override late final _StringsUserAgreementScreenRu UserAgreementScreen = _StringsUserAgreementScreenRu._(_root); - @override late final _StringsVersionUpdateScreenRu VersionUpdateScreen = _StringsVersionUpdateScreenRu._(_root); - @override late final _StringsCommonWidgetRu CommonWidget = _StringsCommonWidgetRu._(_root); - @override late final _StringsServerManagerRu ServerManager = _StringsServerManagerRu._(_root); - @override late final _StringsMainRu main = _StringsMainRu._(_root); - @override String get enable => 'Включить'; - @override String get disable => 'Запретить'; - @override String get prefer => 'Приоритет'; - @override String get only => 'Только'; - @override String get open => 'Открыть'; - @override String get close => 'Закрыть'; - @override String get quit => 'Выйти'; - @override String get add => 'Добавить'; - @override String get remove => 'Удалить'; - @override String get edit => 'Редактировать'; - @override String get view => 'Более'; - @override String get more => 'More'; - @override String get addProfile => 'Добавить профиль'; - @override String get addSuccess => 'Добавлено успешно'; - @override String addSuccessThen({required Object p}) => 'Конфигурация сгенерирована успешно. Для просмотра перейдите в [${p}]'; - @override String addFailed({required Object p}) => 'Ошибка при добавлении:${p}'; - @override String get removeConfirm => 'Подтверждаете удаление?'; - @override String get tips => 'Инфо'; - @override String get copy => 'Скопировать'; - @override String get ok => 'Ок'; - @override String get cancel => 'Закрыть'; - @override String get feedback => 'Обратная связь'; - @override String get faq => 'Часто задаваемые вопросы (FAQ)'; - @override String get download => 'Скачать'; - @override String get loading => 'Загрузка...'; - @override String updateFailed({required Object p}) => 'Не удалось обновить:${p}'; - @override String get days => 'дни'; - @override String get hours => 'часы'; - @override String get minutes => 'минуты'; - @override String get seconds => 'Второй'; - @override String get protocol => 'Протокол'; - @override String get search => 'Поиск'; - @override String get custom => 'Настроить самостоятельно'; - @override String get connect => 'Соединить'; - @override String get disconnect => 'Отключить'; - @override String get connected => 'Подключено'; - @override String get disconnected => 'Отключено'; - @override String get connecting => 'Подключение'; - @override String get connectTimeout => 'Таймаут при соединении'; - @override String get timeout => 'тайм-аут'; - @override String get language => 'Язык'; - @override String get next => 'Дальше'; - @override String get done => 'Готово'; - @override String get apply => 'Применить'; - @override String get refresh => 'Обновить'; - @override String get retry => 'Хотите попробовать еще раз?'; - @override String get none => 'Ничего не делать'; - @override String get reset => 'Перезагрузить'; - @override String get submit => 'Отправить'; - @override String get account => 'Аккаунт'; - @override String get password => 'Пароль'; - @override String get required => 'Необходимо'; - @override String get diversion => 'Правила'; - @override String get diversionRules => 'Правила перенаправления'; - @override String get diversionRulesEnable => 'Включить правила разгрузки [ISP]'; - @override String get diversionCustomGroup => 'Личные правила'; - @override String get diversionCustomGroupPreset => 'Шаблоны личных правил'; - @override String get diversionCustomGroupPresetTips => 'Примечание. Включенные элементы будут добавлены или включены в [Личные правила] и [Правила перенаправления].'; - @override String get diversionCustomGroupAddTips => 'Примечание. Возможно, вам придется вручную настроить сортировку после ее добавления, в противном случае добавленное перенаправление может не вступить в силу.'; - @override String get urlTestCustomGroup => 'Личная группа прокси-серверов'; - @override String get rulesetEnableTips => 'Совет: После включения опции перейдите в [Правила перенаправления] и установите их, иначе опция не будет действовать'; - @override String get ispUserAgentTips => '[ISP] будет доставлять различные типы данных о подписке на основе [UserAgent] в запросе [HTTP].'; - @override String get ispDiversionTips => 'Правила разгрузки, предоставляемые подписками типа [ISP] [V2Ray], не поддерживают правила разгрузки;'; - @override String get staticIP => 'Статический IP'; - @override String get other => 'Другой'; - @override String get dns => 'DNS'; - @override String get url => 'URL'; - @override String get isp => 'ISP'; - @override String get tls => 'TLS'; - @override String get userAgent => 'UserAgent'; - @override String get urlInvalid => 'Неверный URL'; - @override String get outboundActionCurrentSelected => 'Текущий сервер'; - @override String get outboundActionUrltest => 'Автовыбор сервера'; - @override String get outboundActionDirect => 'Напрямую'; - @override String get outboundActionBlock => 'Блокировать'; - @override String get routeFinal => 'Final'; - @override String get rulesetGeoSite => 'GeoSite'; - @override String get rulesetGeoIp => 'GeoIP'; - @override String get rulesetAcl => 'ACL'; - @override String get iCloud => 'iCloud'; - @override String get appleTV => 'Apple TV'; - @override String get webdav => 'Webdav'; - @override String get setting => 'Настройки'; - @override String get protocolSniff => 'Обнаружение протокола'; - @override String get protocolSniffOverrideDestination => 'Обнаруженное доменное имя охватывает целевой адрес подключения.'; - @override String get remark => 'Примечание'; - @override String get remarkCannotEmpty => 'Примечание не может быть пустым'; - @override String get remarkTooLong => 'Примечания до 32 символов'; - @override String get remarkExist => 'Примечание уже существует, используйте другое имя'; - @override String get domainSuffix => 'Суффикс доменного имени'; - @override String get domain => 'Имя домена'; - @override String get domainKeyword => 'Ключевые слова в имени домена'; - @override String get domainRegex => 'Регулярные выражения для имен доменов'; - @override String get ip => 'IP'; - @override String get port => 'Порт'; - @override String get appPackage => 'Имя пакета приложения'; - @override String get processName => 'Имя процесса'; - @override String get processPath => 'Путь к процессу'; - @override String get systemProxy => 'Системный прокси'; - @override String get netInterfaces => 'Сетевой интерфейс'; - @override String get netSpeed => 'Скорость'; - @override String get website => 'Веб-сайт'; - @override String get rule => 'Правила'; - @override String get global => 'Глобально'; - @override String get qrcode => 'QR-код'; - @override String get scanQrcode => 'Сканировать QR-код'; - @override String get scanResult => 'Результат сканирования'; - @override String get backupAndSync => 'Резервное копирование и синхронизация'; - @override String get importAndExport => 'Импорт и экспорт'; - @override String get import => 'Импорт'; - @override String get export => 'Экспорт'; - @override String get termOfUse => 'Условия использования'; - @override String get privacyPolicy => 'Политика конфиденциальности'; - @override String get about => 'О Karing'; - @override String get name => 'Название'; - @override String get version => 'Версия'; - @override String get notice => 'Уведомления'; - @override String get sort => 'Отсортировать'; - @override String get novice => 'Режим новичка'; - @override String get recommended => 'Рекомендуемые'; - @override String innerError({required Object p}) => 'внутренняя ошибка:${p}'; - @override String get logicOperation => 'логическая операция'; - @override String get share => 'Поделиться'; - @override String get candidateWord => 'Ключевые слова'; - @override String get keywordsOrRegx => 'Ключевые слова/регулярные выражения'; - @override String get importFromClipboard => 'Импорт из буфера обмена'; - @override String get exportToClipboard => 'Экспорт в буфер обмена'; - @override String get server => 'сервер'; - @override String get appleTVConnectTurnOfprivateDirect => 'Пожалуйста, сначала включите [Прямое подключение к частной сети]'; - @override String targetConnectFailed({required Object p}) => 'Не удалось подключиться к [${p}]. Убедитесь, что устройство находится в той же локальной сети, и включите [Прямое подключение к частной сети].'; - @override String get appleTVSync => 'Синхронизация текущей базовой конфигурации с Apple TV - Karing'; - @override String get appleTVSyncDone => 'Синхронизация завершена, перейдите в Apple TV — Karing, чтобы открыть/перезапустить соединение.'; - @override String get appleTVRemoveCoreConfig => 'Удаление Apple TV — базовая конфигурация Karing'; - @override String get appleTVRemoveCoreConfigDone => 'Apple TV — основной профиль Karing удален; VPN-сервис отключен;'; - @override String get appleTVUrlInvalid => 'Неверный URL-адрес. Откройте Apple TV — Karing, отсканируйте QR-код, отображаемый Karing.'; - @override String get remoteProfileEditConfirm => 'После обновления конфигурации изменения узла будут восстановлены. Продолжить?'; - @override String invalidFileType({required Object p}) => 'Неверный тип файла:${p}'; - @override Map get locales => { - 'en': 'English', - 'zh-CN': '简体中文', - 'ar': 'عربي', - 'ru': 'Русский', - 'fa': 'فارسی', - }; -} - -// Path: AboutScreen -class _StringsAboutScreenRu implements _StringsAboutScreenEn { - _StringsAboutScreenRu._(this._root); - - @override final _StringsRu _root; // ignore: unused_field - - // Translations - @override String get installRefer => 'Установленная ссылка'; - @override String get versionChannel => 'Автоматически обновлять канал'; - @override String get disableUAReport => 'Отключить аналитику'; - @override String get disableUAReportTip => 'Отчеты о поведенческих данных помогают нам улучшить работу с продуктом; версии ниже основной версии автоматически отключают все отчеты о данных (кроме [Активации приложения]).'; - @override String get devOptions => 'Параметры разработчика'; - @override String get enableDebugLog => 'Включить debug-лог'; - @override String get viewFilsContent => 'Посмотреть файлы'; - @override String get enablePprof => 'Включить pprof'; - @override String get pprofPanel => 'pprof панель'; - @override String get openDir => 'Открыть каталог файлов'; - @override String get useOriginalSBProfile => 'Использовать исходную конфигурацию Sing-box'; -} - -// Path: AddProfileByImportFromFileScreen -class _StringsAddProfileByImportFromFileScreenRu implements _StringsAddProfileByImportFromFileScreenEn { - _StringsAddProfileByImportFromFileScreenRu._(this._root); - - @override final _StringsRu _root; // ignore: unused_field - - // Translations - @override String get title => 'Импорт файла конфигурации'; - @override String get chooseFile => 'Выбрать файл'; - @override String get configExist => 'Профиль уже существует. Пожалуйста, не добавляйте его повторно'; -} - -// Path: AddProfileByLinkOrContentScreen -class _StringsAddProfileByLinkOrContentScreenRu implements _StringsAddProfileByLinkOrContentScreenEn { - _StringsAddProfileByLinkOrContentScreenRu._(this._root); - - @override final _StringsRu _root; // ignore: unused_field - - // Translations - @override String get title => 'Добавление подписки'; - @override String get updateTimerInterval => 'Интервал обновления'; - @override String get updateTimerIntervalTips => 'Чтобы отключить, установите:< 5 мин'; - @override String get profileLinkContent => 'Ссылка на подписку/содержание'; - @override String get profileLinkContentHit => 'Ссылка на подписку/содержание [обязательно] (Поддерживаются Clash, V2ray(c пакетом поддержки), Stash, Karing, Sing-box, Shadowsocks, Sub; Ссылка на конфигурацию).'; - @override String get subscriptionCannotEmpty => 'Ссылка на подписку не может быть пустой'; - @override String get configExist => 'Профиль уже существует. Пожалуйста, не добавляйте его повторно'; - @override String get invalidUrl => 'Ссылка на подписку слишком длинная'; - @override String addFailedFormatException({required Object p}) => 'Неправильный формат, исправьте его и добавьте еще раз:${p}'; - @override String addFailedThenDownloadAndImport({required Object p}) => 'Не удалось добавить: ${p}. Попробуйте изменить [UserAgent] и повторите попытку, или используйте собственный браузер устройства, чтобы открыть ссылку на конфигурацию и импортировать файл конфигурации, загруженный браузером, в это приложение.'; - @override String addFailedHandshakeException({required Object p}) => 'Не удалось добавить: ${p}, откройте агент или измените текущий узел агента и повторите попытку.'; -} - -// Path: AddProfileByScanQrcodeScanScreen -class _StringsAddProfileByScanQrcodeScanScreenRu implements _StringsAddProfileByScanQrcodeScanScreenEn { - _StringsAddProfileByScanQrcodeScanScreenRu._(this._root); - - @override final _StringsRu _root; // ignore: unused_field - - // Translations - @override String get copy => 'Скопировать ссылку'; - @override String get open => 'Открыть ссылку'; - @override String get requestCameraPermission => 'Пожалуйста, разрешите приложению доступ к камере'; - @override String get requestScreenAccess => 'Пожалуйста, перейдите в «Настройки системы» — «Конфиденциальность и безопасность» — «Запись экрана», чтобы добавить разрешения для этого приложения'; - @override String get screenshot => 'Скриншот'; - @override String get scanFromImage => 'Открыть'; - @override String get scanNoResult => 'Не удалось проанализировать изображение. Убедитесь, что снимок экрана представляет собой действительный QR-код.'; - @override String get scanEmptyResult => 'Пустой результат сканирования.'; - @override String scanException({required Object p}) => 'Не удалось проанализировать изображение. Убедитесь, что снимок экрана представляет собой действительный QR-код:${p}'; -} - -// Path: BackupAndSyncLanSyncScreen -class _StringsBackupAndSyncLanSyncScreenRu implements _StringsBackupAndSyncLanSyncScreenEn { - _StringsBackupAndSyncLanSyncScreenRu._(this._root); - - @override final _StringsRu _root; // ignore: unused_field - - // Translations - @override String get title => 'Синхронизация по локальной сети'; - @override String get lanSyncNotQuitTips => 'Не выходите из этого окна до завершения синхронизации.'; -} - -// Path: BackupAndSyncWebdavScreen -class _StringsBackupAndSyncWebdavScreenRu implements _StringsBackupAndSyncWebdavScreenEn { - _StringsBackupAndSyncWebdavScreenRu._(this._root); - - @override final _StringsRu _root; // ignore: unused_field - - // Translations - @override String get webdavServerUrl => 'Адрес сервера'; - @override String get webdavRequired => 'Не может быть пустым'; - @override String get webdavLoginFailed => 'Ошибка входа:'; - @override String get webdavListFailed => 'Не удалось получить список файлов:'; -} - -// Path: DiversionGroupCustomEditScreen -class _StringsDiversionGroupCustomEditScreenRu implements _StringsDiversionGroupCustomEditScreenEn { - _StringsDiversionGroupCustomEditScreenRu._(this._root); - - @override final _StringsRu _root; // ignore: unused_field - - // Translations - @override String invalidDomain({required Object p}) => 'Неверный [Domain]:${p}'; - @override String invalidIpCidr({required Object p}) => 'Неверный [IP Cidr]:${p}'; - @override String invalidPort({required Object p}) => 'Неверный [Port]:${p}'; - @override String invalidRuleSet({required Object p}) => 'Неверный [Rule Set]:${p}, URL-адрес должен быть действительным URL-адресом https двоичного файлом с расширением .srs/.json'; - @override String invalidRuleSetBuildIn({required Object p}) => 'Неверный [RuleSet(build-in)]:${p}, формат: geosite:xxx или geoip:xxx или acl:xxx, а xxx должно быть допустимым именем правила.'; - @override String get setDiversionRule => 'Совет: после сохранения перейдите в раздел [Правила перенаправления] и установите их, иначе изменения не будут действовать.'; -} - -// Path: DiversionRuleDetectScreen -class _StringsDiversionRuleDetectScreenRu implements _StringsDiversionRuleDetectScreenEn { - _StringsDiversionRuleDetectScreenRu._(this._root); - - @override final _StringsRu _root; // ignore: unused_field - - // Translations - @override String get title => 'Тест правил перенаправления'; - @override String get detect => 'Тест'; - @override String get rule => 'Правило:'; - @override String get outbound => 'Прокси-сервер:'; -} - -// Path: DiversionRulesScreen -class _StringsDiversionRulesScreenRu implements _StringsDiversionRulesScreenEn { - _StringsDiversionRulesScreenRu._(this._root); - - @override final _StringsRu _root; // ignore: unused_field - - // Translations - @override String get diversionRulesMatchTips => 'Совет: Правила применяются по очереди сверху вниз. Если ни одно соответствие не обнаружено, то действует правило [Final]'; -} - -// Path: DnsSettingsScreen -class _StringsDnsSettingsScreenRu implements _StringsDnsSettingsScreenEn { - _StringsDnsSettingsScreenRu._(this._root); - - @override final _StringsRu _root; // ignore: unused_field - - // Translations - @override String get ispCanNotEmpty => 'ISP не может быть пустой'; - @override String get urlCanNotEmpty => 'URL не может быть пустой'; - @override String error({required Object p}) => 'Неподдерживаемый тип:${p}'; - @override String get dnsDesc => 'Первый столбец данных — это задержка запроса при прямом соединении;\nВторой столбец, если включено [[действующий поток]Разрешать DNS через прокси-сервер]: данные — это задержка запроса, пересылаемого через текущий прокси-сервер; Если выключено [[действующий поток] Разрешать DNS через прокси-сервер]: данные - это задержка запроса при прямом соединении.'; -} - -// Path: FeedbackScreen -class _StringsFeedbackScreenRu implements _StringsFeedbackScreenEn { - _StringsFeedbackScreenRu._(this._root); - - @override final _StringsRu _root; // ignore: unused_field - - // Translations - @override String get content => 'Содержание'; - @override String get contentHit => 'Не более 500 символов'; - @override String get contentCannotEmpty => 'Содержание не может быть пустым'; -} - -// Path: FileContentViewerScreen -class _StringsFileContentViewerScreenRu implements _StringsFileContentViewerScreenEn { - _StringsFileContentViewerScreenRu._(this._root); - - @override final _StringsRu _root; // ignore: unused_field - - // Translations - @override String get title => 'Просмотр содержимого файла'; - @override String get chooseFile => 'Выберите файл'; - @override String get clearFileContent => 'Вы уверены, что хотите очистить содержимое файла?'; - @override String get clearFileContentTips => 'Вы уверены, что хотите очистить содержимое файла профиля? Очистка файла профиля может привести к потере данных или некорректной работе приложения. Действуйте осторожно.'; -} - -// Path: HomeScreen -class _StringsHomeScreenRu implements _StringsHomeScreenEn { - _StringsHomeScreenRu._(this._root); - - @override final _StringsRu _root; // ignore: unused_field - - // Translations - @override String get toSelectServer => 'Выберите сервер'; - @override String get invalidServer => 'Просрочен. Пожалуйста, выберите другой'; - @override String get disabledServer => 'Был отключен. Пожалуйста, выберите другой'; - @override String get expiredServer => 'Нет доступного сервера: возможно, профиль устарел или отключен'; - @override String systemProxyTips({required Object sp, required Object hp}) => 'socks:${sp},http(s):${hp}'; - @override String get trafficTotal => 'Трафик всего'; - @override String get trafficProxy => 'Трафик прокси'; - @override String get myLinkEmpty => 'Пожалуйста, настройте [Быструю ссылку] перед использованием'; - @override String get deviceNoSpace => 'Недостаточно места на диске'; - @override String tooMuchServers({required Object p, required Object p1}) => 'Слишком много прокси-серверов [${p}>${p1}], и соединение может оказаться невозможным из-за ограничений системной памяти'; -} - -// Path: LaunchFailedScreen -class _StringsLaunchFailedScreenRu implements _StringsLaunchFailedScreenEn { - _StringsLaunchFailedScreenRu._(this._root); - - @override final _StringsRu _root; // ignore: unused_field - - // Translations - @override String get invalidProcess => 'Не удалось запустить приложение [Неверное имя процесса], переустановите приложение в отдельную папку'; - @override String get invalidProfile => 'Не удалось запустить приложение [Не удалось получить доступ к профилю], переустановите приложение'; - @override String get invalidVersion => 'Не удалось запустить приложение [Неверная версия], переустановите приложение'; - @override String get systemVersionLow => 'Не удалось запустить приложение [Слишком низкая версия системы]'; - @override String get startFromUNC => 'Путь установки недействителен, переустановите его по допустимому пути'; -} - -// Path: MyProfilesEditScreen -class _StringsMyProfilesEditScreenRu implements _StringsMyProfilesEditScreenEn { - _StringsMyProfilesEditScreenRu._(this._root); - - @override final _StringsRu _root; // ignore: unused_field - - // Translations - @override String get title => 'Редактирование профилей'; - @override String get urlExist => 'URL-адрес уже существует, используйте другой URL-адрес'; - @override String get updateTimerInterval => 'Интервал обновления'; - @override String get updateTimerIntervalTips => 'Чтобы отключить, установите <5 мин'; - @override String get reloadAfterProfileUpdate => 'Перезагрузить после обновления профиля'; - @override String get testLatencyAfterProfileUpdate => 'Начать тестирование задержек после обновления профиля'; - @override String get testLatencyAfterProfileUpdateTips => 'VPN необходимо подключить, и включить [Перезагрузить после обновления профиля]'; - @override String get testLatencyAutoRemove => 'Автоматически удалять серверы, не прошедшие тесты на задержку'; - @override String get testLatencyAutoRemoveTips => 'Попробуйте до 3 раз'; -} - -// Path: MyProfilesMergeScreen -class _StringsMyProfilesMergeScreenRu implements _StringsMyProfilesMergeScreenEn { - _StringsMyProfilesMergeScreenRu._(this._root); - - @override final _StringsRu _root; // ignore: unused_field - - // Translations - @override String get profilesMerge => 'Объединение профилей'; - @override String get profilesMergeTarget => 'Целевой профиль'; - @override String get profilesMergeSource => 'Профиль - источник'; - @override String get profilesMergeTips => 'Совет: Настройки перенаправления для профиля - источника будут удалены.'; -} - -// Path: MyProfilesScreen -class _StringsMyProfilesScreenRu implements _StringsMyProfilesScreenEn { - _StringsMyProfilesScreenRu._(this._root); - - @override final _StringsRu _root; // ignore: unused_field - - // Translations - @override String get title => 'Профили'; - @override String get atLeastOneEnable => 'Невозможно отключить, оставьте включенным хотя бы один профиль'; -} - -// Path: NetCheckScreen -class _StringsNetCheckScreenRu implements _StringsNetCheckScreenEn { - _StringsNetCheckScreenRu._(this._root); - - @override final _StringsRu _root; // ignore: unused_field - - // Translations - @override String get title => 'Диагностика сети'; - @override String get warn => 'Примечание. Из-за влияния сетевой среды и правил перенаправления результаты теста не полностью эквивалентны фактическим результатам.'; - @override String get check => 'Тест'; - @override String get invalidDomain => 'Неверное имя домена'; - @override String get connectivity => 'Подключение к сети'; - @override String connectivityTestIpv4AllFailed({required Object p}) => 'Ipv4 Тест подключения[${p}] неудачен'; - @override String get connectivityTestIpv4Ok => 'Ipv4 Соединение выполнено успешно'; - @override String connectivityTestIpv6AllFailed({required Object p}) => 'Ipv6 Тест подключения[${p}] неудачен. Возможно, ваша сеть не поддерживает ipv6.'; - @override String get connectivityTestIpv6Ok => 'Ipv6 Соединение выполнено успешно'; - @override String get connectivityTestOk => 'Сеть подключена к Интернету'; - @override String get connectivityTestFailed => 'Ваша сеть не подключена к Интернету'; - @override String get remoteRulesetsDownloadOk => 'Все успешно скачано'; - @override String get remoteRulesetsDownloadNotOk => 'Загрузка или сбой'; - @override String get outbound => 'Прокси-сервер'; - @override String outboundOk({required Object p}) => '[${p}]Соединение установлено успешно'; - @override String outboundFailed({required Object p1, required Object p2}) => '[${p1}]Соединение не удалось\nошибка:[${p2}]'; - @override String get dnsServer => 'DNS сервер'; - @override String dnsOk({required Object p1, required Object p2, required Object p3, required Object p4}) => '[${p1}]DNS Разобрано успешно\nDNS правило:[${p2}]\nЗадержка:[${p3} ms]\nадрес:[${p4}]'; - @override String dnsFailed({required Object p1, required Object p2, required Object p3}) => '[${p1}]DNS Не удалось выполнить синтаксический анализ\n правило:[${p2}]\nошибка:[${p3}]'; - @override String get host => 'HTTP соединение'; - @override String hostConnection({required Object p1, required Object p2, required Object p3}) => '[${p1}]\nПравила перенаправления:[${p2}]\nПрокси-сервер:[${p3}]'; - @override String get hostConnectionOk => 'Соединение установлено успешно'; - @override String hostConnectionFailed({required Object p}) => 'Соединение не удалось:[${p}]'; -} - -// Path: NetConnectionsFilterScreen -class _StringsNetConnectionsFilterScreenRu implements _StringsNetConnectionsFilterScreenEn { - _StringsNetConnectionsFilterScreenRu._(this._root); - - @override final _StringsRu _root; // ignore: unused_field - - // Translations - @override String get title => 'Фильтр соединений'; - @override String get hostIp => 'Domain/IP'; - @override String get app => 'Приложение'; - @override String get rule => 'Правило'; - @override String get chain => 'Исходящий'; -} - -// Path: NetConnectionsScreen -class _StringsNetConnectionsScreenRu implements _StringsNetConnectionsScreenEn { - _StringsNetConnectionsScreenRu._(this._root); - - @override final _StringsRu _root; // ignore: unused_field - - // Translations - @override String get title => 'Соединения'; - @override String get copyAsCSV => 'Скопировано в CSV формате'; - @override String get selectType => 'Выберите тип перенаправления'; -} - -// Path: PerAppAndroidScreen -class _StringsPerAppAndroidScreenRu implements _StringsPerAppAndroidScreenEn { - _StringsPerAppAndroidScreenRu._(this._root); - - @override final _StringsRu _root; // ignore: unused_field - - // Translations - @override String get title => 'Проксируемые приложения'; - @override String get whiteListMode => 'Режим белого списка'; - @override String get whiteListModeTip => 'Если включено: перенаправляются через прокси-сервер только те приложения, которые были отмечены. Если выключено: перенаправляются через прокси-сервер только те приложения, которые не были отмечены.'; - @override String get hideSystemApp => 'Скрыть системные приложения'; - @override String get hideAppIcon => 'Скрыть значок приложения'; - @override String get enableAppQueryPermission => 'Включать разрешения [на запросы списка приложений]'; -} - -// Path: QrcodeScreen -class _StringsQrcodeScreenRu implements _StringsQrcodeScreenEn { - _StringsQrcodeScreenRu._(this._root); - - @override final _StringsRu _root; // ignore: unused_field - - // Translations - @override String get tooLong => 'Слишком большой текст для отображения'; - @override String get copy => 'Скопировать ссылку'; - @override String get open => 'Открыть ссылку'; - @override String get share => 'Поделиться ссылкой'; - @override String get shareImage => 'Поделиться QR-кодом'; -} - -// Path: RegionSettingsScreen -class _StringsRegionSettingsScreenRu implements _StringsRegionSettingsScreenEn { - _StringsRegionSettingsScreenRu._(this._root); - - @override final _StringsRu _root; // ignore: unused_field - - // Translations - @override String get title => 'Страна или регион'; - @override String get Regions => 'Совет: Пожалуйста, правильно укажите текущую страну или регион. В противном случае это может вызвать проблемы с перенаправлением в сети'; -} - -// Path: ServerSelectScreen -class _StringsServerSelectScreenRu implements _StringsServerSelectScreenEn { - _StringsServerSelectScreenRu._(this._root); - - @override final _StringsRu _root; // ignore: unused_field - - // Translations - @override String get title => 'Выбор сервера'; - @override String get autoSelectServer => 'Автовыбор сервера с наименьшей задержкой'; - @override String get recentUse => 'Недавно использованные'; - @override String get myFav => 'Мои избранные'; - @override String selectLocal({required Object p}) => 'Выбранный сервер является локальным, и может работать неправильно:${p}'; - @override String get selectRequireEnableIPv6 => 'Выбранный сервер имеет адрес IPv6 и требует [Включить IPv6]'; - @override String get selectDisabled => 'Сервер отключен'; - @override String get error404 => 'При измерении задержки произошла ошибка. Проверьте, существует ли профиль с таким содержимым.'; -} - -// Path: SettingsScreen -class _StringsSettingsScreenRu implements _StringsSettingsScreenEn { - _StringsSettingsScreenRu._(this._root); - - @override final _StringsRu _root; // ignore: unused_field - - // Translations - @override String ispFaq({required Object p}) => 'FAQ[${p}]'; - @override String cleanISP({required Object p}) => 'Очистить ISP[${p}]'; - @override String get openISP => 'Открыть ссылку на провайдера'; - @override String get cleanISPNoParam => 'Очистить информацию об интернет-провайдере'; - @override String get getTranffic => 'Получить трафик'; - @override String get tutorial => 'Руководство'; - @override String get commonlyUsedRulesets => 'Часто используемые наборы правил'; - @override String get howToRemoveAds => 'Как удалить рекламу'; - @override String get htmlBoard => 'Веб-панель'; - @override String get dnsLeakDetection => 'Обнаружение утечки DNS'; - @override String get speedTest => 'Тест скорости'; - @override String get downloadProfilePreferProxy => 'Настройка приоритетного выбора прокси-сервера'; - @override String get downloadProfilePreferProxyTips => 'Если подключение установлено, профиль вначале будет загружен через подключенный прокси-сервер'; - @override String get rulesetDirectDownlad => 'Rule Set Прямой доступ'; - @override String get hideUnusedDiversionGroup => 'Скрыть неактивные правила перенаправления'; - @override String get disableISPDiversionGroup => 'Отключить правила перенаправления ISP'; - @override String get portSetting => 'Порт'; - @override String get portSettingRule => 'Основано на правилах'; - @override String get portSettingDirectAll => 'Полное прямое соединение'; - @override String get portSettingProxyAll => 'Прокси для всего'; - @override String get portSettingControl => 'Управление и синхронизация'; - @override String get portSettingCluster => 'Кластерный сервис'; - @override String get modifyPort => 'Изменить порт'; - @override String get ipStrategyTips => 'Перед включением убедитесь, что ваша сеть поддерживает IPv6, в противном случае нормальный доступ к части трафика будет невозможен'; - @override String get tunAppendHttpProxy => 'Подключите HTTP-прокси к VPN'; - @override String get tunAppendHttpProxyTips => 'Некоторые приложения будут обходить устройство виртуальной сетевой карты и напрямую подключаться к HTTP-прокси.'; - @override String get tlsInsecureEnable => 'Пропустить проверку сертификата'; - @override String get tlsFragmentEnable => 'Включить сегментацию TLS'; - @override String get tlsFragmentSize => 'Размер сегмента TLS'; - @override String get tlsFragmentSleep => 'Сегментированный сон TLS'; - @override String get tlsMixedCaseSNIEnable => 'Включить гибридный SNI TLS'; - @override String get tlsPaddingEnable => 'Включить заполнение TLS'; - @override String get tlsPaddingSize => 'Размер заполнения TLS'; - @override String get dnsEnableRule => 'Включить правила DNS'; - @override String get dnsEnableFakeIp => 'Включить FakeIP'; - @override String get dnsEnableClientSubnet => 'Включить ECS'; - @override String get dnsEnableProxyResolveByProxy => '[действующий поток] Разрешать DNS через прокси-сервер'; - @override String get dnsEnableFinalResolveByProxy => '[final] Разрешать DNS через прокси-сервер'; - @override String get dnsTestDomain => 'Тестовое доменное имя'; - @override String get dnsTestDomainInvalid => 'Неверное доменное имя'; - @override String get dnsTypeOutbound => 'Прокси-сервер'; - @override String get dnsTypeDirect => 'Прямой поток'; - @override String get dnsTypeProxy => 'Действующий поток'; - @override String get dnsTypeResolver => 'DNS-сервер'; - @override String get dnsEnableRuleTips => 'После включения, доменное имя выберет соответствующий DNS-сервер для разрешения в соответствии с правилами перенаправления.'; - @override String get dnsEnableFakeIpTips => 'После включения FakeIP, если VPN-соединение отключено, возможно, потребуется перезапустить приложение, эту функцию необходимо включить [Режим TUN];'; - @override String get dnsTypeOutboundTips => 'Для разрешения доменных имен прокси-сервера рекомендуется использовать безопасный DNS'; - @override String get dnsTypeDirectTips => 'Разрешение доменных имен для прямого потока'; - @override String get dnsTypeProxyTips => 'Разрешение доменных имен для действующего потока'; - @override String get dnsTypeResolverTips => 'Разрешение доменных имен для DNS-серверов'; - @override String get dnsTypeFinalTips => 'Разрешение доменных имен для потока Final'; - @override String get dnsAutoSetServer => 'Автоматически настроить сервер'; - @override String get dnsResetServer => 'Сбросить сервер'; - @override String get inboundDomainResolve => 'Разрешение входящих доменных имен'; - @override String get privateDirect => 'Прямое подключение к частной сети'; - @override String inboundDomainResolveTips({required Object p}) => 'Некоторые доменные имена без настроенных правил переадресации необходимо разрешить, прежде чем они смогут соответствовать правилам переадресации на основе IP; эта функция влияет на входящие запросы к порту прокси [${p}]'; - @override String get useRomoteRes => 'Использовать удаленные ресурсы'; - @override String get autoSelect => 'Автовыбор'; - @override String get autoSelectServerIgnorePerProxyServer => 'Игнорировать прокси-сервер [передний прокси]'; - @override String get autoSelectServerInterval => 'Интервал проверок задержки'; - @override String get autoSelectServerReTestIfNetworkUpdate => 'Перетестировать после смены сети'; - @override String get autoSelectServerIntervalTips => 'Чем короче временной интервал, тем чаще обновляются данные о задержке сервера. Но это потребует больше ресурсов и энергии'; - @override String get autoSelectServerFavFirst => 'Приоритетно [Мои избранные]'; - @override String get autoSelectServerUpdateCurrentServerAfterManualUrltest => 'Обновить текущий сервер после измерения задержки вручную'; - @override String get autoSelectServerFavFirstTips => 'Если список [Мои избранные] не пуст, то будут использоваться серверы из [Мои избранные]'; - @override String get autoSelectServerFilter => 'Отфильтровать сервера'; - @override String autoSelectServerFilterTips({required Object p}) => 'Ошибки превышения задержки сервера будут отфильтрованы; если после фильтрации ни один сервер не будет доступен, вместо него будут использоваться первые [${p}] серверы'; - @override String get autoSelectServerLimitedNum => 'Максимальное количество серверов'; - @override String get autoSelectServerLimitedNumTips => 'Серверы, превышающие это число, будут отфильтрованы.'; - @override String get numInvalid => 'Неправильный номер'; - @override String get hideInvalidServer => 'Скрыть нерабочие серверы'; - @override String get sortServer => 'Сортировка серверов'; - @override String get sortServerTips => 'Сортировать по задержке от низкой к высокой'; - @override String get selectServerHideRecommand => 'Скрыть [Рекомендуемые]'; - @override String get selectServerHideRecent => 'Скрыть [Недавно использованные]'; - @override String get selectServerHideFav => 'Скрыть [Мои избранные]'; - @override String get homeScreen => 'Домашний экран'; - @override String get theme => 'Тема'; - @override String get myLink => 'Быстрая ссылка'; - @override String get myLinkInvalid => 'Неверный URL'; - @override String get autoConnectAfterLaunch => 'Автоматическое подключение после запуска'; - @override String get hideAfterLaunch => 'Скрыть окно после запуска'; - @override String get autoSetSystemProxy => 'Установить прокси после подключения'; - @override String get disconnectWhenQuit => 'Отключаться при выходе из приложения'; - @override String get allowBypass => 'Разрешить приложениям обходить VPN'; - @override String get lanSyncTo => 'Синхронизировать на другие устройства'; - @override String get lanSyncFrom => 'Синхронизация с других устройств'; - @override String get lanSyncScanQRcode => 'Сканируйте QR-код для синхронизации'; - @override String get syncToConfirm => 'Подтвердить синхронизацию с собеседником?'; - @override String get syncDone => 'Синхронизация завершена'; - @override String get importSuccess => 'Импорт выполнен успешно'; - @override String get rewriteConfirm => 'Этот файл перезапишет существующую локальную конфигурацию. Продолжить?'; - @override String get networkShare => 'Общий доступ к сети'; - @override String get frontProxy => 'Фронт-прокси'; - @override String get frontProxyTips => 'Запрос -> фронт-прокси сервер -> прокси-сервер -> целевой сервер'; - @override String get allowOtherHostsConnect => 'Разрешить подключаться другим'; - @override String allowOtherHostsConnectTips({required Object sp, required Object hp}) => 'socks:${sp},http(s):${hp}'; - @override String get tunAutoRoute => 'Auto Route'; - @override String get tunStrictRoute => 'Strict Route'; - @override String get tunStrictRouteTips => 'Если после включения общего доступа другие люди не смогут получить доступ к этому устройству, попробуйте отключить этот переключатель.'; - @override String get enableCluster => 'Включить кластер прокси Socks/Http'; - @override String get clusterAllowOtherHostsConnect => 'Разрешить подключаться другим'; - @override String clusterAllowOtherHostsConnectTips({required Object hp}) => 'http://127.0.0.1:${hp}/get_proxies'; - @override String get clusterAuth => 'Аутентификация прокси-кластера'; - @override String get clusterConfirm => 'Пожалуйста, подтвердите, что задержка серверов проверена. Прокси-сервисы не будут созданы, если они не проверены или проверены неверно'; - @override String get tunMode => 'Режим TUN'; - @override String get tunModeTips => 'В режиме TUN весь трафик системы будет перенаправлен через соединение [В этом режиме вы можете оставить системный прокси отключенным]'; - @override String get tunModeRunAsAdmin => 'Для режима TUN требуются права администратора. Перезапустите приложение от имени администратора'; - @override String get tunStack => 'Stack'; - @override String get launchAtStartup => 'Запуск при включении'; - @override String get quitWhenSwitchSystemUser => 'Переключить пользователя для выхода'; - @override String get handleScheme => 'Использовать схему системы с предварительным звонком'; - @override String get portableMode => 'Портативный режим'; - @override String get portableModeDisableTips => 'Если вам нужно выйти из портативного режима, выйдите из [karing] и вручную удалите папку [profiles] в том же каталоге, что и [karing.exe]'; - @override String get handleKaringScheme => 'Кнопка karing:// Позвонить'; - @override String get handleClashScheme => 'Кнопка clash:// Позвонить'; - @override String get handleSingboxScheme => 'Кнопка sing-box:// Позвонить'; - @override String get removeSystemVPNConfig => 'Удалить профиль VPN'; - @override String get timeConnectOrDisconnect => 'Запланированное подключение/отключение'; - @override String get timeConnectOrDisconnectTips => 'Чтобы это заработало, необходимо подключить VPN; после его подключения [автоматическое засыпание] будет отключено'; - @override String timeConnectAndDisconnectInterval({required Object p}) => 'Интервал подключения/отключения не может быть меньше ${p} минут.'; - @override String get disableFontScaler => 'Отключить масштабирование шрифта'; - @override String get autoOrientation => 'Следите за поворотом экрана'; - @override String get restartTakesEffect => 'Требуется перезапуск'; - @override String get resetSettings => 'Сброс настроек'; - @override String get cleanCache => 'Очистка кэша'; - @override String get cleanCacheDone => 'Очистка завершена'; - @override String get appleTestFlight => 'Apple TestFlight'; - @override String get appleAppStore => 'Apple AppStore'; - @override String hasNewVersion({required Object p}) => 'Обновить версию ${p}'; - @override String get follow => 'Подписаться на нас'; - @override String get contactUs => 'Связаться с нами'; - @override String get rateInApp => 'Оценить нас'; - @override String get rateInAppStore => 'Оценить нас в App Store'; -} - -// Path: SpeedTestSettingsScreen -class _StringsSpeedTestSettingsScreenRu implements _StringsSpeedTestSettingsScreenEn { - _StringsSpeedTestSettingsScreenRu._(this._root); - - @override final _StringsRu _root; // ignore: unused_field - - // Translations - @override String get title => 'URL-адрес теста скорости'; - @override String get error => 'https URL должен быть действительным'; -} - -// Path: TextToQrCodeScreen -class _StringsTextToQrCodeScreenRu implements _StringsTextToQrCodeScreenEn { - _StringsTextToQrCodeScreenRu._(this._root); - - @override final _StringsRu _root; // ignore: unused_field - - // Translations - @override String get title => 'Преобразование текста в QR-код'; - @override String get convert => 'Конвертировать'; -} - -// Path: UrlTestSettingsScreen -class _StringsUrlTestSettingsScreenRu implements _StringsUrlTestSettingsScreenEn { - _StringsUrlTestSettingsScreenRu._(this._root); - - @override final _StringsRu _root; // ignore: unused_field - - // Translations - @override String get title => 'URL-адрес измерения задержки'; - @override String get error => 'https URL должен быть действительным'; -} - -// Path: UserAgreementScreen -class _StringsUserAgreementScreenRu implements _StringsUserAgreementScreenEn { - _StringsUserAgreementScreenRu._(this._root); - - @override final _StringsRu _root; // ignore: unused_field - - // Translations - @override String get privacyFirst => 'Ваша конфиденциальность превыше всего'; - @override String get agreeAndContinue => 'Принять и продолжить'; -} - -// Path: VersionUpdateScreen -class _StringsVersionUpdateScreenRu implements _StringsVersionUpdateScreenEn { - _StringsVersionUpdateScreenRu._(this._root); - - @override final _StringsRu _root; // ignore: unused_field - - // Translations - @override String versionReady({required Object p}) => 'Новая версия [${p}] доступна'; - @override String get update => 'Перезапустить'; - @override String get cancel => 'Не сейчас'; -} - -// Path: CommonWidget -class _StringsCommonWidgetRu implements _StringsCommonWidgetEn { - _StringsCommonWidgetRu._(this._root); - - @override final _StringsRu _root; // ignore: unused_field - - // Translations - @override String get diableAlwayOnVPN => 'Если параметр [VPN всегда включен] включен, отключите его и попробуйте подключиться еще раз'; - @override String get resetPort => 'Пожалуйста, измените порт на другой доступный порт или закройте приложение, занимающее порт.'; -} - -// Path: ServerManager -class _StringsServerManagerRu implements _StringsServerManagerEn { - _StringsServerManagerRu._(this._root); - - @override final _StringsRu _root; // ignore: unused_field - - // Translations - @override String get noServerAvaliable => 'Нет доступных серверов, убедитесь что подписка или файл профиля корректен. Если ваша конфигурация взята из GitHub, получите адрес ссылки, нажав кнопку [Raw] на странице.'; - @override String get filePathCannotEmpty => 'Путь к файлу не может быть пустым'; - @override String fileNotExist({required Object p}) => 'Файла не существует:${p}'; - @override String get urlCannotEmpty => 'Ссылка не может быть пустой'; - @override String get invalidUrl => 'Некорректная ссылка на подписку'; - @override String get parseFailed => 'Получение подписки не удалось'; -} - -// Path: main -class _StringsMainRu implements _StringsMainEn { - _StringsMainRu._(this._root); - - @override final _StringsRu _root; // ignore: unused_field - - // Translations - @override late final _StringsMainTrayRu tray = _StringsMainTrayRu._(_root); -} - -// Path: main.tray -class _StringsMainTrayRu implements _StringsMainTrayEn { - _StringsMainTrayRu._(this._root); - - @override final _StringsRu _root; // ignore: unused_field - - // Translations - @override String get menuOpen => ' Открыть '; - @override String get menuExit => ' Выйти '; -} - -// Path: -class _StringsZhCn implements Translations { - /// You can call this constructor and build your own translation instance of this locale. - /// Constructing via the enum [AppLocale.build] is preferred. - _StringsZhCn.build({Map? overrides, PluralResolver? cardinalResolver, PluralResolver? ordinalResolver}) - : assert(overrides == null, 'Set "translation_overrides: true" in order to enable this feature.'), - $meta = TranslationMetadata( - locale: AppLocale.zhCn, - overrides: overrides ?? {}, - cardinalResolver: cardinalResolver, - ordinalResolver: ordinalResolver, - ) { - $meta.setFlatMapFunction(_flatMapFunction); - } - - /// Metadata for the translations of . - @override final TranslationMetadata $meta; - - /// Access flat map - @override dynamic operator[](String key) => $meta.getTranslation(key); - - @override late final _StringsZhCn _root = this; // ignore: unused_field - - // Translations - @override late final _StringsAboutScreenZhCn AboutScreen = _StringsAboutScreenZhCn._(_root); - @override late final _StringsAddProfileByImportFromFileScreenZhCn AddProfileByImportFromFileScreen = _StringsAddProfileByImportFromFileScreenZhCn._(_root); - @override late final _StringsAddProfileByLinkOrContentScreenZhCn AddProfileByLinkOrContentScreen = _StringsAddProfileByLinkOrContentScreenZhCn._(_root); - @override late final _StringsAddProfileByScanQrcodeScanScreenZhCn AddProfileByScanQrcodeScanScreen = _StringsAddProfileByScanQrcodeScanScreenZhCn._(_root); - @override late final _StringsBackupAndSyncLanSyncScreenZhCn BackupAndSyncLanSyncScreen = _StringsBackupAndSyncLanSyncScreenZhCn._(_root); - @override late final _StringsBackupAndSyncWebdavScreenZhCn BackupAndSyncWebdavScreen = _StringsBackupAndSyncWebdavScreenZhCn._(_root); - @override late final _StringsDiversionGroupCustomEditScreenZhCn DiversionGroupCustomEditScreen = _StringsDiversionGroupCustomEditScreenZhCn._(_root); - @override late final _StringsDiversionRuleDetectScreenZhCn DiversionRuleDetectScreen = _StringsDiversionRuleDetectScreenZhCn._(_root); - @override late final _StringsDiversionRulesScreenZhCn DiversionRulesScreen = _StringsDiversionRulesScreenZhCn._(_root); - @override late final _StringsDnsSettingsScreenZhCn DnsSettingsScreen = _StringsDnsSettingsScreenZhCn._(_root); - @override late final _StringsFeedbackScreenZhCn FeedbackScreen = _StringsFeedbackScreenZhCn._(_root); - @override late final _StringsFileContentViewerScreenZhCn FileContentViewerScreen = _StringsFileContentViewerScreenZhCn._(_root); - @override late final _StringsHomeScreenZhCn HomeScreen = _StringsHomeScreenZhCn._(_root); - @override late final _StringsLaunchFailedScreenZhCn LaunchFailedScreen = _StringsLaunchFailedScreenZhCn._(_root); - @override late final _StringsMyProfilesEditScreenZhCn MyProfilesEditScreen = _StringsMyProfilesEditScreenZhCn._(_root); - @override late final _StringsMyProfilesMergeScreenZhCn MyProfilesMergeScreen = _StringsMyProfilesMergeScreenZhCn._(_root); - @override late final _StringsMyProfilesScreenZhCn MyProfilesScreen = _StringsMyProfilesScreenZhCn._(_root); - @override late final _StringsNetCheckScreenZhCn NetCheckScreen = _StringsNetCheckScreenZhCn._(_root); - @override late final _StringsNetConnectionsFilterScreenZhCn NetConnectionsFilterScreen = _StringsNetConnectionsFilterScreenZhCn._(_root); - @override late final _StringsNetConnectionsScreenZhCn NetConnectionsScreen = _StringsNetConnectionsScreenZhCn._(_root); - @override late final _StringsPerAppAndroidScreenZhCn PerAppAndroidScreen = _StringsPerAppAndroidScreenZhCn._(_root); - @override late final _StringsQrcodeScreenZhCn QrcodeScreen = _StringsQrcodeScreenZhCn._(_root); - @override late final _StringsRegionSettingsScreenZhCn RegionSettingsScreen = _StringsRegionSettingsScreenZhCn._(_root); - @override late final _StringsServerSelectScreenZhCn ServerSelectScreen = _StringsServerSelectScreenZhCn._(_root); - @override late final _StringsSettingsScreenZhCn SettingsScreen = _StringsSettingsScreenZhCn._(_root); - @override late final _StringsSpeedTestSettingsScreenZhCn SpeedTestSettingsScreen = _StringsSpeedTestSettingsScreenZhCn._(_root); - @override late final _StringsTextToQrCodeScreenZhCn TextToQrCodeScreen = _StringsTextToQrCodeScreenZhCn._(_root); - @override late final _StringsUrlTestSettingsScreenZhCn UrlTestSettingsScreen = _StringsUrlTestSettingsScreenZhCn._(_root); - @override late final _StringsUserAgreementScreenZhCn UserAgreementScreen = _StringsUserAgreementScreenZhCn._(_root); - @override late final _StringsVersionUpdateScreenZhCn VersionUpdateScreen = _StringsVersionUpdateScreenZhCn._(_root); - @override late final _StringsCommonWidgetZhCn CommonWidget = _StringsCommonWidgetZhCn._(_root); - @override late final _StringsServerManagerZhCn ServerManager = _StringsServerManagerZhCn._(_root); - @override late final _StringsMainZhCn main = _StringsMainZhCn._(_root); - @override String get enable => '启用'; - @override String get disable => '禁用'; - @override String get prefer => '优先'; - @override String get only => '仅'; - @override String get open => '打开'; - @override String get close => '关闭'; - @override String get quit => '退出'; - @override String get add => '添加'; - @override String get remove => '删除'; - @override String get edit => '编辑'; - @override String get view => '查看'; - @override String get more => '更多'; - @override String get addProfile => '添加配置'; - @override String get addSuccess => '添加成功'; - @override String addSuccessThen({required Object p}) => '配置生成成功,请到[${p}]查看'; - @override String addFailed({required Object p}) => '添加失败:${p}'; - @override String get removeConfirm => '确认删除?'; - @override String get tips => '提示'; - @override String get copy => '拷贝'; - @override String get ok => '确定'; - @override String get cancel => '取消'; - @override String get feedback => '反馈'; - @override String get faq => '常见问题'; - @override String get download => '下载'; - @override String get loading => '加载中...'; - @override String updateFailed({required Object p}) => '更新失败:${p}'; - @override String get days => '天'; - @override String get hours => '时'; - @override String get minutes => '分'; - @override String get seconds => '秒'; - @override String get protocol => '协议'; - @override String get search => '搜索'; - @override String get custom => '自定义'; - @override String get connect => '连接'; - @override String get disconnect => '断开'; - @override String get connected => '已连接'; - @override String get disconnected => '未连接'; - @override String get connecting => '连接中'; - @override String get connectTimeout => '连接超时'; - @override String get timeout => '超时'; - @override String get language => '语言'; - @override String get next => '下一步'; - @override String get done => '完成'; - @override String get apply => '应用'; - @override String get refresh => '刷新'; - @override String get retry => '是否重试?'; - @override String get none => '无'; - @override String get reset => '重置'; - @override String get submit => '提交'; - @override String get account => '账号'; - @override String get password => '密码'; - @override String get required => '必填'; - @override String get diversion => '分流'; - @override String get diversionRules => '分流规则'; - @override String get diversionRulesEnable => '启用[ISP]分流规则'; - @override String get diversionCustomGroup => '自定义分流组'; - @override String get diversionCustomGroupPreset => '预置[自定义分流组]'; - @override String get diversionCustomGroupPresetTips => '注意:启用的项会添加/覆盖到[自定义分流组]和[分流规则]'; - @override String get diversionCustomGroupAddTips => '注意:添加完毕后可能需要手动调整排序,否则新添加的分流可能不会生效'; - @override String get urlTestCustomGroup => '自定义代理组'; - @override String get rulesetEnableTips => '提示:开启选项后,请到[分流规则]设置相关规则,否则不会生效'; - @override String get ispUserAgentTips => '[ISP]会根据[HTTP]请求里的[UserAgent]下发不同订阅类型的数据'; - @override String get ispDiversionTips => '[ISP]提供的分流规则;[V2Ray]类型的订阅不支持分流规则'; - @override String get staticIP => '静态IP'; - @override String get other => '其他'; - @override String get dns => 'DNS'; - @override String get url => 'URL'; - @override String get isp => 'ISP'; - @override String get tls => 'TLS'; - @override String get userAgent => 'UserAgent'; - @override String get urlInvalid => '无效URL'; - @override String get outboundActionCurrentSelected => '当前选择'; - @override String get outboundActionUrltest => '自动选择'; - @override String get outboundActionDirect => '直连'; - @override String get outboundActionBlock => '拦截'; - @override String get routeFinal => 'final'; - @override String get rulesetGeoSite => 'GeoSite'; - @override String get rulesetGeoIp => 'GeoIP'; - @override String get rulesetAcl => 'ACL'; - @override String get iCloud => 'iCloud'; - @override String get appleTV => 'Apple TV'; - @override String get webdav => 'Webdav'; - @override String get setting => '设置'; - @override String get protocolSniff => '协议探测'; - @override String get protocolSniffOverrideDestination => '探测的域名覆盖连接目标地址'; - @override String get remark => '备注'; - @override String get remarkCannotEmpty => '备注不能为空'; - @override String get remarkTooLong => '备注最长32字符'; - @override String get remarkExist => '备注已存在,请使用其他名称'; - @override String get domainSuffix => '域名后缀'; - @override String get domain => '域名'; - @override String get domainKeyword => '域名关键词'; - @override String get domainRegex => '域名正则'; - @override String get ip => 'IP'; - @override String get port => '端口'; - @override String get appPackage => '应用包名'; - @override String get processName => '进程名称'; - @override String get processPath => '进程路径'; - @override String get systemProxy => '系统代理'; - @override String get netInterfaces => '网络接口'; - @override String get netSpeed => '速度'; - @override String get website => '官网'; - @override String get rule => '规则'; - @override String get global => '全局'; - @override String get qrcode => '二维码'; - @override String get scanQrcode => '扫描二维码'; - @override String get scanResult => '扫描结果'; - @override String get backupAndSync => '备份与同步'; - @override String get importAndExport => '导入/导出'; - @override String get import => '导入'; - @override String get export => '导出'; - @override String get termOfUse => '使用条款'; - @override String get privacyPolicy => '隐私政策'; - @override String get about => '关于'; - @override String get name => '名称'; - @override String get version => '版本'; - @override String get notice => '通知'; - @override String get sort => '排序'; - @override String get novice => '新手模式'; - @override String get recommended => '推荐'; - @override String innerError({required Object p}) => '内部错误:${p}'; - @override String get logicOperation => '逻辑运算'; - @override String get share => '分享'; - @override String get candidateWord => '候选词'; - @override String get keywordsOrRegx => '关键词/正则'; - @override String get importFromClipboard => '从剪切板导入'; - @override String get exportToClipboard => '导出到剪切板'; - @override String get server => '服务器'; - @override String get appleTVConnectTurnOfprivateDirect => '请先开启[私有网络直连]'; - @override String targetConnectFailed({required Object p}) => '连接[${p}]失败,请确保设备在同一个局域网内,并且开启[私有网络直连]'; - @override String get appleTVSync => '同步当前核心配置到Apple TV - Karing'; - @override String get appleTVSyncDone => '同步完成,请到Apple TV - Karing开启连接/重启连接'; - @override String get appleTVRemoveCoreConfig => '删除Apple TV - Karing核心配置'; - @override String get appleTVRemoveCoreConfigDone => 'Apple TV - Karing的核心配置文件已删除;VPN服务已断开连接'; - @override String get appleTVUrlInvalid => '无效的URL,请打开Apple TV - Karing,扫描Karing显示的二维码'; - @override String get remoteProfileEditConfirm => '配置更新后,节点的修改将会被还原,是否继续?'; - @override String invalidFileType({required Object p}) => '无效的文件类型:${p}'; - @override Map get locales => { - 'en': 'English', - 'zh-CN': '简体中文', - 'ar': 'عربي', - 'ru': 'Русский', - 'fa': 'فارسی', - }; -} - -// Path: AboutScreen -class _StringsAboutScreenZhCn implements _StringsAboutScreenEn { - _StringsAboutScreenZhCn._(this._root); - - @override final _StringsZhCn _root; // ignore: unused_field - - // Translations - @override String get installRefer => '安装参考'; - @override String get versionChannel => '自动更新通道'; - @override String get disableUAReport => '关闭行为数据上报'; - @override String get disableUAReportTip => '行为数据上报有助于我们改进产品体验;低于主版本的版本将自动关闭的所有数据上报([应用激活]除外)'; - @override String get devOptions => '开发者选项'; - @override String get enableDebugLog => '开启调试日志'; - @override String get viewFilsContent => '查看文件'; - @override String get enablePprof => '启用pprof'; - @override String get pprofPanel => 'pprof面板'; - @override String get openDir => '打开文件目录'; - @override String get useOriginalSBProfile => '使用原始sing-box配置'; -} - -// Path: AddProfileByImportFromFileScreen -class _StringsAddProfileByImportFromFileScreenZhCn implements _StringsAddProfileByImportFromFileScreenEn { - _StringsAddProfileByImportFromFileScreenZhCn._(this._root); - - @override final _StringsZhCn _root; // ignore: unused_field - - // Translations - @override String get title => '导入配置文件'; - @override String get chooseFile => '选择文件'; - @override String get configExist => '配置已存在,请勿重复添加'; -} - -// Path: AddProfileByLinkOrContentScreen -class _StringsAddProfileByLinkOrContentScreenZhCn implements _StringsAddProfileByLinkOrContentScreenEn { - _StringsAddProfileByLinkOrContentScreenZhCn._(this._root); - - @override final _StringsZhCn _root; // ignore: unused_field - - // Translations - @override String get title => '添加配置链接'; - @override String get updateTimerInterval => '更新时间间隔'; - @override String get updateTimerIntervalTips => '禁用请设置为:<5m'; - @override String get profileLinkContent => '配置链接/内容'; - @override String get profileLinkContentHit => '配置链接/内容[必填] (支持Clash,V2ray(支持批量),Stash,Karing,Sing-box,Shadowsocks,Sub,Github配置链接)'; - @override String get subscriptionCannotEmpty => '配置链接不能为空'; - @override String get configExist => '配置已存在,请勿重复添加'; - @override String get invalidUrl => '配置链接长度过长'; - @override String addFailedFormatException({required Object p}) => '格式错误,请订正后重新添加:${p}'; - @override String addFailedThenDownloadAndImport({required Object p}) => '添加失败:${p}, 请尝试修改[UserAgent]后重试,或者用设备自带的浏览器打开配置链接,并将浏览器下载的配置文件导入到本应用'; - @override String addFailedHandshakeException({required Object p}) => '添加失败:${p}, 请打开代理或者修改当前代理节点后重试'; -} - -// Path: AddProfileByScanQrcodeScanScreen -class _StringsAddProfileByScanQrcodeScanScreenZhCn implements _StringsAddProfileByScanQrcodeScanScreenEn { - _StringsAddProfileByScanQrcodeScanScreenZhCn._(this._root); - - @override final _StringsZhCn _root; // ignore: unused_field - - // Translations - @override String get copy => '拷贝链接'; - @override String get open => '打开链接'; - @override String get requestCameraPermission => '请开启摄像头权限'; - @override String get requestScreenAccess => '请到系统设置-隐私与安全-屏幕录制 为本应用添加权限'; - @override String get screenshot => '截图'; - @override String get scanFromImage => '打开二维码图片'; - @override String get scanNoResult => '解析图片失败,请确保截图为有效的二维码'; - @override String get scanEmptyResult => '扫描结果为空'; - @override String scanException({required Object p}) => '解析图片异常,请确保截图为有效的二维码:${p}'; -} - -// Path: BackupAndSyncLanSyncScreen -class _StringsBackupAndSyncLanSyncScreenZhCn implements _StringsBackupAndSyncLanSyncScreenEn { - _StringsBackupAndSyncLanSyncScreenZhCn._(this._root); - - @override final _StringsZhCn _root; // ignore: unused_field - - // Translations - @override String get title => '局域网同步'; - @override String get lanSyncNotQuitTips => '同步完成前请勿退出此界面'; -} - -// Path: BackupAndSyncWebdavScreen -class _StringsBackupAndSyncWebdavScreenZhCn implements _StringsBackupAndSyncWebdavScreenEn { - _StringsBackupAndSyncWebdavScreenZhCn._(this._root); - - @override final _StringsZhCn _root; // ignore: unused_field - - // Translations - @override String get webdavServerUrl => '服务器地址'; - @override String get webdavRequired => '不能为空'; - @override String get webdavLoginFailed => '登录失败:'; - @override String get webdavListFailed => '获取文件列表失败:'; -} - -// Path: DiversionGroupCustomEditScreen -class _StringsDiversionGroupCustomEditScreenZhCn implements _StringsDiversionGroupCustomEditScreenEn { - _StringsDiversionGroupCustomEditScreenZhCn._(this._root); - - @override final _StringsZhCn _root; // ignore: unused_field - - // Translations - @override String invalidDomain({required Object p}) => '无效的 [Domain]:${p}'; - @override String invalidIpCidr({required Object p}) => '无效的 [IP Cidr]:${p}'; - @override String invalidPort({required Object p}) => '无效的 [Port]:${p}'; - @override String invalidRuleSet({required Object p}) => '无效的 [Rule Set]:${p}, URL必须是有效的https URL,并且文件扩展名为.srs/.json的binary文件'; - @override String invalidRuleSetBuildIn({required Object p}) => '无效的 [Rule Set(build-in)]:${p}, 格式为geosite:xxx 或 geoip:xxx 或 acl:xxx,并且xxx应为有效的规则名'; - @override String get setDiversionRule => '提示:保存后,请到[分流规则]设置相关规则,否则不会生效'; -} - -// Path: DiversionRuleDetectScreen -class _StringsDiversionRuleDetectScreenZhCn implements _StringsDiversionRuleDetectScreenEn { - _StringsDiversionRuleDetectScreenZhCn._(this._root); - - @override final _StringsZhCn _root; // ignore: unused_field - - // Translations - @override String get title => '分流规则探测'; - @override String get detect => '探测'; - @override String get rule => '规则:'; - @override String get outbound => '代理服务器:'; -} - -// Path: DiversionRulesScreen -class _StringsDiversionRulesScreenZhCn implements _StringsDiversionRulesScreenEn { - _StringsDiversionRulesScreenZhCn._(this._root); - - @override final _StringsZhCn _root; // ignore: unused_field - - // Translations - @override String get diversionRulesMatchTips => '提示:从上到下依次尝试匹配规则,如果没有匹配到规则,则使用[final]'; -} - -// Path: DnsSettingsScreen -class _StringsDnsSettingsScreenZhCn implements _StringsDnsSettingsScreenEn { - _StringsDnsSettingsScreenZhCn._(this._root); - - @override final _StringsZhCn _root; // ignore: unused_field - - // Translations - @override String get ispCanNotEmpty => 'ISP 不能为空'; - @override String get urlCanNotEmpty => 'URL 不能为空'; - @override String error({required Object p}) => '不支持的类型:${p}'; - @override String get dnsDesc => '第一列延迟数据为直连查询延迟;\n第二列:开启[[代理流量]通过代理服务器解析DNS]:延迟数据为通过当前代理服务器转发的查询延迟;未开启[[代理流量]通过代理服务器解析DNS]:延迟数据为直连查询延迟'; -} - -// Path: FeedbackScreen -class _StringsFeedbackScreenZhCn implements _StringsFeedbackScreenEn { - _StringsFeedbackScreenZhCn._(this._root); - - @override final _StringsZhCn _root; // ignore: unused_field - - // Translations - @override String get content => '反馈内容'; - @override String get contentHit => '必填, 最长500字符'; - @override String get contentCannotEmpty => '反馈内容不能为空'; -} - -// Path: FileContentViewerScreen -class _StringsFileContentViewerScreenZhCn implements _StringsFileContentViewerScreenEn { - _StringsFileContentViewerScreenZhCn._(this._root); - - @override final _StringsZhCn _root; // ignore: unused_field - - // Translations - @override String get title => '文件内容查看'; - @override String get chooseFile => '选择文件'; - @override String get clearFileContent => '确认清空文件内容?'; - @override String get clearFileContentTips => '确认清空配置文件内容? 清空配置文件可能会导致数据丢失或应用功能异常, 请谨慎操作'; -} - -// Path: HomeScreen -class _StringsHomeScreenZhCn implements _StringsHomeScreenEn { - _StringsHomeScreenZhCn._(this._root); - - @override final _StringsZhCn _root; // ignore: unused_field - - // Translations - @override String get toSelectServer => '请选择服务器'; - @override String get invalidServer => '已失效,请重新选择'; - @override String get disabledServer => '已被禁用,请重新选择'; - @override String get expiredServer => '无可用服务器:配置可能已过期或被禁用'; - @override String systemProxyTips({required Object sp, required Object hp}) => 'socks:${sp},http(s):${hp}'; - @override String get trafficTotal => '总流量'; - @override String get trafficProxy => '代理流量'; - @override String get myLinkEmpty => '请先设置[快捷链接]后再使用'; - @override String get deviceNoSpace => '磁盘空间不足'; - @override String tooMuchServers({required Object p, required Object p1}) => '代理服务器[${p}>${p1}]过多,可能因系统内存限制而无法连接'; -} - -// Path: LaunchFailedScreen -class _StringsLaunchFailedScreenZhCn implements _StringsLaunchFailedScreenEn { - _StringsLaunchFailedScreenZhCn._(this._root); - - @override final _StringsZhCn _root; // ignore: unused_field - - // Translations - @override String get invalidProcess => '应用启动失败[无效的进程名称],请重新安装应用到独立目录'; - @override String get invalidProfile => '应用启动失败[访问配置文件失败],请重新安装应用'; - @override String get invalidVersion => '应用启动失败[无效版本],请重新安装应用'; - @override String get systemVersionLow => '应用启动失败[系统版本过低]'; - @override String get startFromUNC => '无效的安装路径,请重新安装到有效路径'; -} - -// Path: MyProfilesEditScreen -class _StringsMyProfilesEditScreenZhCn implements _StringsMyProfilesEditScreenEn { - _StringsMyProfilesEditScreenZhCn._(this._root); - - @override final _StringsZhCn _root; // ignore: unused_field - - // Translations - @override String get title => '编辑配置'; - @override String get urlExist => 'URL已存在,请使用其他URL'; - @override String get updateTimerInterval => '更新时间间隔'; - @override String get updateTimerIntervalTips => '禁用请设置为:<5m'; - @override String get reloadAfterProfileUpdate => '配置更新后重新加载'; - @override String get testLatencyAfterProfileUpdate => '配置自动更新后启动延迟测试'; - @override String get testLatencyAfterProfileUpdateTips => 'VPN需要处于已连接状态,并且开启[配置更新后重新加载]'; - @override String get testLatencyAutoRemove => '自动移除延迟测试失败的服务器'; - @override String get testLatencyAutoRemoveTips => '最多尝试3次'; -} - -// Path: MyProfilesMergeScreen -class _StringsMyProfilesMergeScreenZhCn implements _StringsMyProfilesMergeScreenEn { - _StringsMyProfilesMergeScreenZhCn._(this._root); - - @override final _StringsZhCn _root; // ignore: unused_field - - // Translations - @override String get profilesMerge => '配置合并'; - @override String get profilesMergeTarget => '目标配置'; - @override String get profilesMergeSource => '源配置'; - @override String get profilesMergeTips => '提示:源配置的分流信息将会被丢弃'; -} - -// Path: MyProfilesScreen -class _StringsMyProfilesScreenZhCn implements _StringsMyProfilesScreenEn { - _StringsMyProfilesScreenZhCn._(this._root); - - @override final _StringsZhCn _root; // ignore: unused_field - - // Translations - @override String get title => '我的配置'; - @override String get atLeastOneEnable => '无法禁用,请至少保留一个配置可用'; -} - -// Path: NetCheckScreen -class _StringsNetCheckScreenZhCn implements _StringsNetCheckScreenEn { - _StringsNetCheckScreenZhCn._(this._root); - - @override final _StringsZhCn _root; // ignore: unused_field - - // Translations - @override String get title => '网络检测'; - @override String get warn => '注意:由于受网络环境及分流规则等影响,测试结果并不完全等价实际中使用的效果'; - @override String get check => '检测'; - @override String get invalidDomain => '无效域名'; - @override String get connectivity => '网络联通性'; - @override String connectivityTestIpv4AllFailed({required Object p}) => 'Ipv4 连接测试[${p}]全部失败'; - @override String get connectivityTestIpv4Ok => 'Ipv4 连接成功'; - @override String connectivityTestIpv6AllFailed({required Object p}) => 'Ipv6 连接测试[${p}]全部失败, 你的网络可能不支持ipv6'; - @override String get connectivityTestIpv6Ok => 'Ipv6 连接成功'; - @override String get connectivityTestOk => '网络已接入互联网'; - @override String get connectivityTestFailed => '网络尚未接入互联网'; - @override String get remoteRulesetsDownloadOk => '全部下载成功'; - @override String get remoteRulesetsDownloadNotOk => '正在下载或下载失败'; - @override String get outbound => '代理服务器'; - @override String outboundOk({required Object p}) => '[${p}]连接成功'; - @override String outboundFailed({required Object p1, required Object p2}) => '[${p1}]连接失败\n错误:[${p2}]'; - @override String get dnsServer => 'DNS服务器'; - @override String dnsOk({required Object p1, required Object p2, required Object p3, required Object p4}) => '[${p1}]域名解析成功\nDNS规则:[${p2}]\n延迟:[${p3} ms]\n地址:[${p4}]'; - @override String dnsFailed({required Object p1, required Object p2, required Object p3}) => '[${p1}]域名解析失败\n规则:[${p2}]\n错误:[${p3}]'; - @override String get host => 'HTTP连接'; - @override String hostConnection({required Object p1, required Object p2, required Object p3}) => '[${p1}]\n分流规则:[${p2}]\n代理服务器:[${p3}]'; - @override String get hostConnectionOk => '连接成功'; - @override String hostConnectionFailed({required Object p}) => '连接失败:[${p}]'; -} - -// Path: NetConnectionsFilterScreen -class _StringsNetConnectionsFilterScreenZhCn implements _StringsNetConnectionsFilterScreenEn { - _StringsNetConnectionsFilterScreenZhCn._(this._root); - - @override final _StringsZhCn _root; // ignore: unused_field - - // Translations - @override String get title => '连接状态筛选'; - @override String get hostIp => '域名/IP'; - @override String get app => '应用'; - @override String get rule => '规则'; - @override String get chain => '出站'; -} - -// Path: NetConnectionsScreen -class _StringsNetConnectionsScreenZhCn implements _StringsNetConnectionsScreenEn { - _StringsNetConnectionsScreenZhCn._(this._root); - - @override final _StringsZhCn _root; // ignore: unused_field - - // Translations - @override String get title => '连接状态'; - @override String get copyAsCSV => '已复制为CSV格式'; - @override String get selectType => '选择分流类型'; -} - -// Path: PerAppAndroidScreen -class _StringsPerAppAndroidScreenZhCn implements _StringsPerAppAndroidScreenEn { - _StringsPerAppAndroidScreenZhCn._(this._root); - - @override final _StringsZhCn _root; // ignore: unused_field - - // Translations - @override String get title => '分应用代理'; - @override String get whiteListMode => '白名单模式'; - @override String get whiteListModeTip => '启用后:仅代理已勾选的App;未启用:仅代理未勾选的App'; - @override String get hideSystemApp => '隐藏系统应用'; - @override String get hideAppIcon => '隐藏应用图标'; - @override String get enableAppQueryPermission => '开启 [获取应用列表] 权限'; -} - -// Path: QrcodeScreen -class _StringsQrcodeScreenZhCn implements _StringsQrcodeScreenEn { - _StringsQrcodeScreenZhCn._(this._root); - - @override final _StringsZhCn _root; // ignore: unused_field - - // Translations - @override String get tooLong => '文本过长,无法展示'; - @override String get copy => '拷贝链接'; - @override String get open => '打开链接'; - @override String get share => '分享链接'; - @override String get shareImage => '分享二维码'; -} - -// Path: RegionSettingsScreen -class _StringsRegionSettingsScreenZhCn implements _StringsRegionSettingsScreenEn { - _StringsRegionSettingsScreenZhCn._(this._root); - - @override final _StringsZhCn _root; // ignore: unused_field - - // Translations - @override String get title => '国家与地区'; - @override String get Regions => '提示:请正确设置你当前所在国家或地区,否则可能会导致分流错误'; -} - -// Path: ServerSelectScreen -class _StringsServerSelectScreenZhCn implements _StringsServerSelectScreenEn { - _StringsServerSelectScreenZhCn._(this._root); - - @override final _StringsZhCn _root; // ignore: unused_field - - // Translations - @override String get title => '选择服务器'; - @override String get autoSelectServer => '自动选择延迟最低的服务器'; - @override String get recentUse => '最近使用'; - @override String get myFav => '我的收藏'; - @override String selectLocal({required Object p}) => '所选服务器为本地地址,可能无法正常使用:${p}'; - @override String get selectRequireEnableIPv6 => '所选服务器为IPv6地址,需要[启用IPv6]'; - @override String get selectDisabled => '该服务器已被禁用'; - @override String get error404 => '延迟检测遇到错误,请检查是否存在内容相同的配置'; -} - -// Path: SettingsScreen -class _StringsSettingsScreenZhCn implements _StringsSettingsScreenEn { - _StringsSettingsScreenZhCn._(this._root); - - @override final _StringsZhCn _root; // ignore: unused_field - - // Translations - @override String ispFaq({required Object p}) => 'FAQ[${p}]'; - @override String cleanISP({required Object p}) => '清除ISP[${p}]'; - @override String get openISP => '打开ISP链接'; - @override String get cleanISPNoParam => '清除ISP信息'; - @override String get getTranffic => '获取流量'; - @override String get tutorial => '使用教程'; - @override String get commonlyUsedRulesets => '常用规则集'; - @override String get howToRemoveAds => '如何移除广告'; - @override String get htmlBoard => '在线面板'; - @override String get dnsLeakDetection => 'DNS泄露检测'; - @override String get speedTest => '测速'; - @override String get downloadProfilePreferProxy => '优先使用代理下载配置'; - @override String get downloadProfilePreferProxyTips => '如果当前已连接,则优先通过已连接的代理下载配置'; - @override String get rulesetDirectDownlad => 'Rule Set直连下载'; - @override String get hideUnusedDiversionGroup => '隐藏未启用的分流组'; - @override String get disableISPDiversionGroup => '禁用ISP分流规则'; - @override String get portSetting => '端口'; - @override String get portSettingRule => '基于规则'; - @override String get portSettingDirectAll => '全直连'; - @override String get portSettingProxyAll => '全代理'; - @override String get portSettingControl => '控制与同步'; - @override String get portSettingCluster => '集群服务'; - @override String get modifyPort => '修改端口'; - @override String get ipStrategyTips => '启用前,请先确认你的网络已支持IPv6,否则某些流量无法正常访问'; - @override String get tunAppendHttpProxy => '附加HTTP代理到VPN'; - @override String get tunAppendHttpProxyTips => '一些App会绕过虚拟网卡设备直连HTTP代理'; - @override String get tlsInsecureEnable => '跳过证书验证'; - @override String get tlsFragmentEnable => '启用TLS分段'; - @override String get tlsFragmentSize => 'TLS分段大小'; - @override String get tlsFragmentSleep => 'TLS分段休眠'; - @override String get tlsMixedCaseSNIEnable => '启用TLS混合SNI'; - @override String get tlsPaddingEnable => '启用TLS填充'; - @override String get tlsPaddingSize => 'TLS填充大小'; - @override String get dnsEnableRule => '启用DNS分流规则'; - @override String get dnsEnableFakeIp => '启用FakeIP'; - @override String get dnsEnableClientSubnet => '启用ECS'; - @override String get dnsEnableProxyResolveByProxy => '[代理流量]通过代理服务器解析DNS'; - @override String get dnsEnableFinalResolveByProxy => '[final]通过代理服务器解析DNS'; - @override String get dnsTestDomain => '测试域名'; - @override String get dnsTestDomainInvalid => '无效的域名'; - @override String get dnsTypeOutbound => '代理服务器'; - @override String get dnsTypeDirect => '直连流量'; - @override String get dnsTypeProxy => '代理流量'; - @override String get dnsTypeResolver => 'DNS服务器'; - @override String get dnsEnableRuleTips => '启用后,域名会根据分流规则选择对应的DNS服务器进行解析'; - @override String get dnsEnableFakeIpTips => '启用FakeIP后,如果断开VPN连接,你的应用可能需要重启;此功能需要开启[TUN模式]'; - @override String get dnsTypeOutboundTips => '用于代理服务器的域名解析'; - @override String get dnsTypeDirectTips => '用于直连流量的域名解析'; - @override String get dnsTypeProxyTips => '用于代理流量的域名解析'; - @override String get dnsTypeResolverTips => '用于DNS服务器的域名解析'; - @override String get dnsTypeFinalTips => '用于其他流量的域名解析'; - @override String get dnsAutoSetServer => '自动设置服务器'; - @override String get dnsResetServer => '重置服务器'; - @override String get inboundDomainResolve => '解析入站域名'; - @override String get privateDirect => '私有网络直连'; - @override String inboundDomainResolveTips({required Object p}) => '某些未配置分流规则的域名需要解析后才可能命中基于IP的分流规则;此功能影响代理端口[${p}]的入站请求'; - @override String get useRomoteRes => '使用远程资源'; - @override String get autoSelect => '自动选择'; - @override String get autoSelectServerIgnorePerProxyServer => '忽略[前置代理]代理服务器'; - @override String get autoSelectServerInterval => '延迟检测时间间隔'; - @override String get autoSelectServerReTestIfNetworkUpdate => '网络变化时重新检测'; - @override String get autoSelectServerUpdateCurrentServerAfterManualUrltest => '手动延时检测后更新当前服务器'; - @override String get autoSelectServerIntervalTips => '延迟检测时间间隔越短,服务器延迟数据更新越及时,但会占用更多资源,耗电更快'; - @override String get autoSelectServerFavFirst => '优先使用[我的收藏]'; - @override String get autoSelectServerFavFirstTips => '如果[我的收藏]列表不为空,则使用[我的收藏]里的服务器'; - @override String get autoSelectServerFilter => '过滤无效服务器'; - @override String autoSelectServerFilterTips({required Object p}) => '服务器延迟检测失败的将会被过滤掉;如果过滤后无服务器可用,则改用前[${p}]个服务器'; - @override String get autoSelectServerLimitedNum => '服务器数量上限'; - @override String get autoSelectServerLimitedNumTips => '超过该数量的服务器将被过滤掉'; - @override String get numInvalid => '无效的数字'; - @override String get hideInvalidServer => '隐藏无效服务器'; - @override String get sortServer => '服务器排序'; - @override String get sortServerTips => '按延迟由低到高排序'; - @override String get selectServerHideRecommand => '隐藏[推荐]'; - @override String get selectServerHideRecent => '隐藏[最近使用]'; - @override String get selectServerHideFav => '隐藏[我的收藏]'; - @override String get homeScreen => '主屏'; - @override String get theme => '主题'; - @override String get myLink => '快捷链接'; - @override String get myLinkInvalid => '无效的URL'; - @override String get autoConnectAfterLaunch => '启动后自动连接'; - @override String get hideAfterLaunch => '启动后隐藏窗口'; - @override String get autoSetSystemProxy => '连接后自动设置系统代理'; - @override String get disconnectWhenQuit => '退出应用时关闭连接'; - @override String get allowBypass => '允许应用绕过VPN'; - @override String get lanSyncTo => '同步给他人'; - @override String get lanSyncFrom => '从他人同步'; - @override String get lanSyncScanQRcode => '扫码同步'; - @override String get syncToConfirm => '确认同步给对方?'; - @override String get syncDone => '同步完成'; - @override String get importSuccess => '导入成功'; - @override String get rewriteConfirm => '该文件将覆盖本地已有配置,是否继续?'; - @override String get networkShare => '网络共享'; - @override String get frontProxy => '前置代理'; - @override String get frontProxyTips => '数据->前置代理服务器->代理服务器->目标服务器'; - @override String get allowOtherHostsConnect => '允许其他主机接入'; - @override String allowOtherHostsConnectTips({required Object sp, required Object hp}) => 'socks:${sp},http(s):${hp}'; - @override String get tunAutoRoute => 'Auto Route'; - @override String get tunStrictRoute => '严格路由'; - @override String get tunStrictRouteTips => '如果开启共享后,其他无法接入此设备,请尝试关闭此开关'; - @override String get enableCluster => '开启Socks/Http代理集群'; - @override String get clusterAllowOtherHostsConnect => '允许其他主机接入代理集群'; - @override String clusterAllowOtherHostsConnectTips({required Object hp}) => 'http://127.0.0.1:${hp}/get_proxies'; - @override String get clusterAuth => '代理集群认证'; - @override String get clusterConfirm => '请确认服务器已经过服务器延迟检测,未检测或者检测出错的将不会创建代理服务'; - @override String get tunMode => 'TUN模式'; - @override String get tunModeTips => 'TUN模式将接管系统所有流量[此模式下无需开启系统代理]'; - @override String get tunModeRunAsAdmin => 'TUN模式需要系统管理员权限,请以管理员身份重新启动应用'; - @override String get tunStack => '网络栈'; - @override String get launchAtStartup => '开机启动'; - @override String get quitWhenSwitchSystemUser => '切换系统用户时退出应用'; - @override String get handleScheme => '系统Scheme调用'; - @override String get portableMode => '便携模式'; - @override String get portableModeDisableTips => '如需退出便携模式,请退出[karing]后,手动删除[karing.exe]同目录下的[profiles]文件夹即可'; - @override String get handleKaringScheme => '处理karing://调用'; - @override String get handleClashScheme => '处理clash://调用'; - @override String get handleSingboxScheme => '处理sing-box://调用'; - @override String get removeSystemVPNConfig => '删除系统VPN配置'; - @override String get timeConnectOrDisconnect => '定时连接/断开'; - @override String get timeConnectOrDisconnectTips => 'VPN必须处于连接状态才会生效;开启后,[自动休眠]将失效'; - @override String timeConnectAndDisconnectInterval({required Object p}) => '连接/断开时间间隔不能低于${p}分钟'; - @override String get disableFontScaler => '禁用字体缩放'; - @override String get autoOrientation => '跟随屏幕旋转'; - @override String get restartTakesEffect => '重启生效'; - @override String get resetSettings => '重置设置'; - @override String get cleanCache => '清理缓存'; - @override String get cleanCacheDone => '清理完成'; - @override String get appleTestFlight => '苹果 TestFlight'; - @override String get appleAppStore => '苹果 AppStore'; - @override String hasNewVersion({required Object p}) => '更新版本 ${p}'; - @override String get follow => '关注我们'; - @override String get contactUs => '联系我们'; - @override String get rateInApp => '评分'; - @override String get rateInAppStore => '在App Store上评分'; -} - -// Path: SpeedTestSettingsScreen -class _StringsSpeedTestSettingsScreenZhCn implements _StringsSpeedTestSettingsScreenEn { - _StringsSpeedTestSettingsScreenZhCn._(this._root); - - @override final _StringsZhCn _root; // ignore: unused_field - - // Translations - @override String get title => '测速URL'; - @override String get error => '必须为有效的 https URL'; -} - -// Path: TextToQrCodeScreen -class _StringsTextToQrCodeScreenZhCn implements _StringsTextToQrCodeScreenEn { - _StringsTextToQrCodeScreenZhCn._(this._root); - - @override final _StringsZhCn _root; // ignore: unused_field - - // Translations - @override String get title => '文本转二维码'; - @override String get convert => '转换'; -} - -// Path: UrlTestSettingsScreen -class _StringsUrlTestSettingsScreenZhCn implements _StringsUrlTestSettingsScreenEn { - _StringsUrlTestSettingsScreenZhCn._(this._root); - - @override final _StringsZhCn _root; // ignore: unused_field - - // Translations - @override String get title => '延迟检测URL'; - @override String get error => '必须为有效的 https URL'; -} - -// Path: UserAgreementScreen -class _StringsUserAgreementScreenZhCn implements _StringsUserAgreementScreenEn { - _StringsUserAgreementScreenZhCn._(this._root); - - @override final _StringsZhCn _root; // ignore: unused_field - - // Translations - @override String get privacyFirst => '您的隐私很重要'; - @override String get agreeAndContinue => '接受并继续'; -} - -// Path: VersionUpdateScreen -class _StringsVersionUpdateScreenZhCn implements _StringsVersionUpdateScreenEn { - _StringsVersionUpdateScreenZhCn._(this._root); - - @override final _StringsZhCn _root; // ignore: unused_field - - // Translations - @override String versionReady({required Object p}) => '新版本[${p}]已就绪'; - @override String get update => '重启更新'; - @override String get cancel => '暂不更新'; -} - -// Path: CommonWidget -class _StringsCommonWidgetZhCn implements _StringsCommonWidgetEn { - _StringsCommonWidgetZhCn._(this._root); - - @override final _StringsZhCn _root; // ignore: unused_field - - // Translations - @override String get diableAlwayOnVPN => '如果开启了[始终开启VPN], 请关闭[始终开启VPN]后重试连接'; - @override String get resetPort => '请将端口改为其他可用端口或者关闭占用该端口的应用'; -} - -// Path: ServerManager -class _StringsServerManagerZhCn implements _StringsServerManagerEn { - _StringsServerManagerZhCn._(this._root); - - @override final _StringsZhCn _root; // ignore: unused_field - - // Translations - @override String get noServerAvaliable => '无可用服务器,请确保配置链接或配置文件有效;如果你的配置来源于GitHub,请从页面上的[Raw]按钮获取链接地址'; - @override String get filePathCannotEmpty => '文件路径不能为空'; - @override String fileNotExist({required Object p}) => '文件不存在:${p}'; - @override String get urlCannotEmpty => '链接不能为空'; - @override String get invalidUrl => '错误的配置链接'; - @override String get parseFailed => '解析配置失败'; -} - -// Path: main -class _StringsMainZhCn implements _StringsMainEn { - _StringsMainZhCn._(this._root); - - @override final _StringsZhCn _root; // ignore: unused_field - - // Translations - @override late final _StringsMainTrayZhCn tray = _StringsMainTrayZhCn._(_root); -} - -// Path: main.tray -class _StringsMainTrayZhCn implements _StringsMainTrayEn { - _StringsMainTrayZhCn._(this._root); - - @override final _StringsZhCn _root; // ignore: unused_field - - // Translations - @override String get menuOpen => ' 打开 '; - @override String get menuExit => ' 退出 '; -} - -/// Flat map(s) containing all translations. -/// Only for edge cases! For simple maps, use the map function of this library. - -extension on Translations { - dynamic _flatMapFunction(String path) { - switch (path) { - case 'AboutScreen.installRefer': return 'Install Refer'; - case 'AboutScreen.versionChannel': return 'Auto Update Channel'; - case 'AboutScreen.disableUAReport': return 'Turn Off Action Data Report'; - case 'AboutScreen.disableUAReportTip': return 'Behavioral data reporting helps us improve the product experience; versions lower than the main version will automatically turn off all data reporting (except [App Activation])'; - case 'AboutScreen.devOptions': return 'Developer Options'; - case 'AboutScreen.enableDebugLog': return 'Enable Debug Log'; - case 'AboutScreen.viewFilsContent': return 'View Files'; - case 'AboutScreen.enablePprof': return 'Enable pprof'; - case 'AboutScreen.pprofPanel': return 'pprof Panel'; - case 'AboutScreen.openDir': return 'Open File Directory'; - case 'AboutScreen.useOriginalSBProfile': return 'Use original sing-box Profile'; - case 'AddProfileByImportFromFileScreen.title': return 'Import Profile File'; - case 'AddProfileByImportFromFileScreen.chooseFile': return 'Select File'; - case 'AddProfileByImportFromFileScreen.configExist': return 'The Profile already exists, please do not add it repeatedly'; - case 'AddProfileByLinkOrContentScreen.title': return 'Add Profile Link'; - case 'AddProfileByLinkOrContentScreen.updateTimerInterval': return 'Update interval'; - case 'AddProfileByLinkOrContentScreen.updateTimerIntervalTips': return 'To disable please set to:<5m'; - case 'AddProfileByLinkOrContentScreen.profileLinkContent': return 'Profile Link/Content'; - case 'AddProfileByLinkOrContentScreen.profileLinkContentHit': return 'Profile Link/Content [Required] (Support Clash,V2ray(batch supported),Stash,Karing,Sing-box,Shadowsocks,Sub Profile links)'; - case 'AddProfileByLinkOrContentScreen.subscriptionCannotEmpty': return 'Profile Link can not be empty'; - case 'AddProfileByLinkOrContentScreen.configExist': return 'The Profile already exists, please do not add it repeatedly'; - case 'AddProfileByLinkOrContentScreen.invalidUrl': return 'The Profile Link is too long'; - case 'AddProfileByLinkOrContentScreen.addFailedFormatException': return ({required Object p}) => 'The format is wrong, please correct it and add it again:${p}'; - case 'AddProfileByLinkOrContentScreen.addFailedThenDownloadAndImport': return ({required Object p}) => 'Add failed: ${p}, please try to modify the [UserAgent] and try again, or use the device\'s built-in browser to open the configuration link and import the configuration file downloaded by the browser into this application'; - case 'AddProfileByLinkOrContentScreen.addFailedHandshakeException': return ({required Object p}) => 'Add failed: ${p}, please tun on the proxy or modify the current proxy node and try again'; - case 'AddProfileByScanQrcodeScanScreen.copy': return 'Copy Link'; - case 'AddProfileByScanQrcodeScanScreen.open': return 'Open Link'; - case 'AddProfileByScanQrcodeScanScreen.requestCameraPermission': return 'Please enable camera permission'; - case 'AddProfileByScanQrcodeScanScreen.requestScreenAccess': return 'Please go to System Settings - Privacy and Security - Screen Recording to add permissions for this application'; - case 'AddProfileByScanQrcodeScanScreen.screenshot': return 'Screenshot'; - case 'AddProfileByScanQrcodeScanScreen.scanFromImage': return 'Scan From Image'; - case 'AddProfileByScanQrcodeScanScreen.scanNoResult': return 'Failed to parse the image, please make sure the screenshot is a valid QR code'; - case 'AddProfileByScanQrcodeScanScreen.scanEmptyResult': return 'Scan Result is empty'; - case 'AddProfileByScanQrcodeScanScreen.scanException': return ({required Object p}) => 'Failed to parse the image, please make sure the screenshot is a valid QR code:${p}'; - case 'BackupAndSyncLanSyncScreen.title': return 'LAN Sync'; - case 'BackupAndSyncLanSyncScreen.lanSyncNotQuitTips': return 'Do not exit this interface before synchronization is completed'; - case 'BackupAndSyncWebdavScreen.webdavServerUrl': return 'Server Url'; - case 'BackupAndSyncWebdavScreen.webdavRequired': return 'Can not be empty'; - case 'BackupAndSyncWebdavScreen.webdavLoginFailed': return 'Login failed:'; - case 'BackupAndSyncWebdavScreen.webdavListFailed': return 'Failed to get file list:'; - case 'DiversionGroupCustomEditScreen.invalidDomain': return ({required Object p}) => 'Invalid [Domain]:${p}'; - case 'DiversionGroupCustomEditScreen.invalidIpCidr': return ({required Object p}) => 'Invalid [IP Cidr]:${p}'; - case 'DiversionGroupCustomEditScreen.invalidPort': return ({required Object p}) => 'Invalid [Port]:${p}'; - case 'DiversionGroupCustomEditScreen.invalidRuleSet': return ({required Object p}) => 'Invalid [Rule Set]:${p}, The URL must be a valid https URL and a binary file with the file extension .srs/.json'; - case 'DiversionGroupCustomEditScreen.invalidRuleSetBuildIn': return ({required Object p}) => 'Invalid [Rule Set(build-in)]:${p}, The format is geosite:xxx or geoip:xxx or acl:xxx, and xxx should be a valid rule name'; - case 'DiversionGroupCustomEditScreen.setDiversionRule': return 'Tip: After saving, please go to [Diversion Rules] to set relevant rules, otherwise they will not take effect'; - case 'DiversionRuleDetectScreen.title': return 'Diversion Rule Detect'; - case 'DiversionRuleDetectScreen.detect': return 'Detect'; - case 'DiversionRuleDetectScreen.rule': return 'Rule:'; - case 'DiversionRuleDetectScreen.outbound': return 'Proxy Server:'; - case 'DiversionRulesScreen.diversionRulesMatchTips': return 'Tip: Try to match the rules from top to bottom. If no rule is matched, use [final]'; - case 'DnsSettingsScreen.ispCanNotEmpty': return 'ISP can not be empty'; - case 'DnsSettingsScreen.urlCanNotEmpty': return 'URL can not be empty'; - case 'DnsSettingsScreen.error': return ({required Object p}) => 'Unsupported type:${p}'; - case 'DnsSettingsScreen.dnsDesc': return 'The first column of delay data is the direct connection query delay;\nThe second column: Turn on [[Proxy Traffic]Resolve DNS through proxy server]: the delay data is the query delay forwarded through the current proxy server; if the [[Proxy Traffic]Resolve DNS through proxy server]: The delay data is the direct connection query delay'; - case 'FeedbackScreen.content': return 'Feedback Content'; - case 'FeedbackScreen.contentHit': return 'Required, up to 500 characters'; - case 'FeedbackScreen.contentCannotEmpty': return 'Feedback content can not be empty'; - case 'FileContentViewerScreen.title': return 'File Content Viewer'; - case 'FileContentViewerScreen.chooseFile': return 'Select File'; - case 'FileContentViewerScreen.clearFileContent': return 'Are you sure to clear the content of the file?'; - case 'FileContentViewerScreen.clearFileContentTips': return 'Are you sure to clear the content of the Profile file? Clearing the Profile file may cause data loss or abnormal application functions, please operate with caution'; - case 'HomeScreen.toSelectServer': return 'Please Select a Server'; - case 'HomeScreen.invalidServer': return 'is invalid, please choose again'; - case 'HomeScreen.disabledServer': return 'is disabled, please choose again'; - case 'HomeScreen.expiredServer': return 'No servers available, profiles may be expired or disabled'; - case 'HomeScreen.systemProxyTips': return ({required Object sp, required Object hp}) => 'socks:${sp},http(s):${hp}'; - case 'HomeScreen.trafficTotal': return 'Traffic Total'; - case 'HomeScreen.trafficProxy': return 'Traffic Proxy'; - case 'HomeScreen.myLinkEmpty': return 'Please set up [Shortcut Link] before using it'; - case 'HomeScreen.deviceNoSpace': return 'Not enough disk space'; - case 'HomeScreen.tooMuchServers': return ({required Object p, required Object p1}) => 'Too many proxy servers [${p}>${p1}], and the connection may fail due to system memory limitations'; - case 'LaunchFailedScreen.invalidProcess': return 'The app failed to start [Invalid process name], please reinstall the app to a separate directory'; - case 'LaunchFailedScreen.invalidProfile': return 'The app failed to start [Failed to access the profile], please reinstall the app'; - case 'LaunchFailedScreen.invalidVersion': return 'The app failed to start [Invalid version], please reinstall the app'; - case 'LaunchFailedScreen.systemVersionLow': return 'The app failed to start [system version too low]'; - case 'LaunchFailedScreen.startFromUNC': return 'The installation path is invalid, please reinstall it to a valid path'; - case 'MyProfilesEditScreen.title': return 'Profile Edit'; - case 'MyProfilesEditScreen.urlExist': return 'URL already exists, please use another URL'; - case 'MyProfilesEditScreen.updateTimerInterval': return 'Update interval'; - case 'MyProfilesEditScreen.updateTimerIntervalTips': return 'To disable please set to:<5m'; - case 'MyProfilesEditScreen.reloadAfterProfileUpdate': return 'Reload after Profile update'; - case 'MyProfilesEditScreen.testLatencyAfterProfileUpdate': return 'Start latency tests after Profile Automatically update'; - case 'MyProfilesEditScreen.testLatencyAfterProfileUpdateTips': return 'VPN needs to be connected, and [Reload after Profile update] Enabled'; - case 'MyProfilesEditScreen.testLatencyAutoRemove': return 'Automatically remove servers that fail latency tests'; - case 'MyProfilesEditScreen.testLatencyAutoRemoveTips': return 'Try up to 3 times'; - case 'MyProfilesMergeScreen.profilesMerge': return 'Profiles Merge'; - case 'MyProfilesMergeScreen.profilesMergeTarget': return 'Target Profile'; - case 'MyProfilesMergeScreen.profilesMergeSource': return 'Source Profiles'; - case 'MyProfilesMergeScreen.profilesMergeTips': return 'Tip: Diversion of the source profiles will be discarded'; - case 'MyProfilesScreen.title': return 'Profiles'; - case 'MyProfilesScreen.atLeastOneEnable': return 'Cannot be disabled, please keep at least one profile enable'; - case 'NetCheckScreen.title': return 'Net Check'; - case 'NetCheckScreen.warn': return 'Note: Due to the influence of network environment and diversion rules, the test results are not completely equivalent to the actual results.'; - case 'NetCheckScreen.check': return 'Check'; - case 'NetCheckScreen.invalidDomain': return 'Invalid Domain Name'; - case 'NetCheckScreen.connectivity': return 'Network Connectivity'; - case 'NetCheckScreen.connectivityTestIpv4AllFailed': return ({required Object p}) => 'Ipv4 Connection test [${p}] all failed'; - case 'NetCheckScreen.connectivityTestIpv4Ok': return 'Ipv4 connection succeeded'; - case 'NetCheckScreen.connectivityTestIpv6AllFailed': return ({required Object p}) => 'Ipv6 Connection test [${p}] all failed, Your network may not support ipv6'; - case 'NetCheckScreen.connectivityTestIpv6Ok': return 'Ipv6 connection succeeded'; - case 'NetCheckScreen.connectivityTestOk': return 'The network is connected to the Internet'; - case 'NetCheckScreen.connectivityTestFailed': return 'The network is not yet connected to the Internet'; - case 'NetCheckScreen.remoteRulesetsDownloadOk': return 'All downloaded successfully'; - case 'NetCheckScreen.remoteRulesetsDownloadNotOk': return 'Downloading or download failed'; - case 'NetCheckScreen.outbound': return 'Proxy Server'; - case 'NetCheckScreen.outboundOk': return ({required Object p}) => '[${p}] connection succeeded'; - case 'NetCheckScreen.outboundFailed': return ({required Object p1, required Object p2}) => '[${p1}] connection failed\nError:[${p2}]'; - case 'NetCheckScreen.dnsServer': return 'DNS Server'; - case 'NetCheckScreen.dnsOk': return ({required Object p1, required Object p2, required Object p3, required Object p4}) => '[${p1}]DNS query succeeded\nDNS Rule:[${p2}]\nLatency:[${p3} ms]\nAddress:[${p4}]'; - case 'NetCheckScreen.dnsFailed': return ({required Object p1, required Object p2, required Object p3}) => '[${p1}]DNS query succeeded\n nDNS Rule:[${p2}]\nError:[${p3}]'; - case 'NetCheckScreen.host': return 'HTTP Connection'; - case 'NetCheckScreen.hostConnection': return ({required Object p1, required Object p2, required Object p3}) => '[${p1}]\nDiversionRule:[${p2}]\nProxy Server:[${p3}]'; - case 'NetCheckScreen.hostConnectionOk': return 'connection succeeded'; - case 'NetCheckScreen.hostConnectionFailed': return ({required Object p}) => 'connection failed:[${p}]'; - case 'NetConnectionsFilterScreen.title': return 'Connections Filter'; - case 'NetConnectionsFilterScreen.hostIp': return 'Domain/IP'; - case 'NetConnectionsFilterScreen.app': return 'App'; - case 'NetConnectionsFilterScreen.rule': return 'Rule'; - case 'NetConnectionsFilterScreen.chain': return 'Outbound'; - case 'NetConnectionsScreen.title': return 'Connections'; - case 'NetConnectionsScreen.copyAsCSV': return 'Copied to CSV format'; - case 'NetConnectionsScreen.selectType': return 'Select Diversion Type'; - case 'PerAppAndroidScreen.title': return 'Per-App Proxy'; - case 'PerAppAndroidScreen.whiteListMode': return 'Whitelist Mode'; - case 'PerAppAndroidScreen.whiteListModeTip': return 'When enabled: only the apps that have been checked are proxies; when not enabled: only the apps that are not checked are proxies'; - case 'PerAppAndroidScreen.hideSystemApp': return 'Hide System Apps'; - case 'PerAppAndroidScreen.hideAppIcon': return 'Hide App Icons'; - case 'PerAppAndroidScreen.enableAppQueryPermission': return 'Turn on [App list query] Permission'; - case 'QrcodeScreen.tooLong': return 'The text is too long to display'; - case 'QrcodeScreen.copy': return 'Copy Link'; - case 'QrcodeScreen.open': return 'Open Link'; - case 'QrcodeScreen.share': return 'Share Link'; - case 'QrcodeScreen.shareImage': return 'Share QR Code'; - case 'RegionSettingsScreen.title': return 'Country Or Region'; - case 'RegionSettingsScreen.Regions': return 'Tip: Please set your current country or region correctly, otherwise it may cause network diversion problems'; - case 'ServerSelectScreen.title': return 'Select Server'; - case 'ServerSelectScreen.autoSelectServer': return 'Auto select the server with the lowest latency'; - case 'ServerSelectScreen.recentUse': return 'Recently Used'; - case 'ServerSelectScreen.myFav': return 'My Favs'; - case 'ServerSelectScreen.selectLocal': return ({required Object p}) => 'The selected server is a local address and may not work properly:${p}'; - case 'ServerSelectScreen.selectRequireEnableIPv6': return 'The selected server is an IPv6 address and requires [Enable IPv6]'; - case 'ServerSelectScreen.selectDisabled': return 'This server has been disabled'; - case 'ServerSelectScreen.error404': return 'Latency detection encountered an error, please check if there is a configuration with the same content'; - case 'SettingsScreen.ispFaq': return ({required Object p}) => 'FAQ[${p}]'; - case 'SettingsScreen.cleanISP': return ({required Object p}) => 'Clear ISP[${p}]'; - case 'SettingsScreen.openISP': return 'Open ISP link'; - case 'SettingsScreen.cleanISPNoParam': return 'Clear ISP Info'; - case 'SettingsScreen.getTranffic': return 'Get Traffic'; - case 'SettingsScreen.tutorial': return 'Tutorial'; - case 'SettingsScreen.commonlyUsedRulesets': return 'Commonly Used Rulesets'; - case 'SettingsScreen.howToRemoveAds': return 'How to remove ads'; - case 'SettingsScreen.htmlBoard': return 'Online Panel'; - case 'SettingsScreen.dnsLeakDetection': return 'DNS Leaks Detection'; - case 'SettingsScreen.speedTest': return 'Speed Test'; - case 'SettingsScreen.downloadProfilePreferProxy': return 'Prefer Proxy to Download Profile'; - case 'SettingsScreen.downloadProfilePreferProxyTips': return 'If currently connected, the profile will be downloaded through the connected proxy first'; - case 'SettingsScreen.rulesetDirectDownlad': return 'Rule Set Direct Download'; - case 'SettingsScreen.hideUnusedDiversionGroup': return 'Hide Unused Diversion Groups'; - case 'SettingsScreen.disableISPDiversionGroup': return 'Disable ISP Diversion Rules'; - case 'SettingsScreen.portSetting': return 'Port'; - case 'SettingsScreen.portSettingRule': return 'Rule Based'; - case 'SettingsScreen.portSettingDirectAll': return 'Direct All'; - case 'SettingsScreen.portSettingProxyAll': return 'Proxy All'; - case 'SettingsScreen.portSettingControl': return 'Control and Sync'; - case 'SettingsScreen.portSettingCluster': return 'Cluster Service'; - case 'SettingsScreen.modifyPort': return 'Modify Port'; - case 'SettingsScreen.ipStrategyTips': return 'Before enabling, please confirm that your network supports IPv6, otherwise some traffic cannot be accessed normally.'; - case 'SettingsScreen.tunAppendHttpProxy': return 'Append HTTP Proxy to VPN'; - case 'SettingsScreen.tunAppendHttpProxyTips': return 'Some apps will bypass virtual NIC Device and directly connect to HTTP proxy'; - case 'SettingsScreen.tlsInsecureEnable': return 'Skip Certificate Verification'; - case 'SettingsScreen.tlsFragmentEnable': return 'Enable TLS Fragment'; - case 'SettingsScreen.tlsFragmentSize': return 'TLS Fragment Size'; - case 'SettingsScreen.tlsFragmentSleep': return 'TLS Fragment Sleep'; - case 'SettingsScreen.tlsMixedCaseSNIEnable': return 'Enable TLS Mixed SNI'; - case 'SettingsScreen.tlsPaddingEnable': return 'Enable TLS Padding'; - case 'SettingsScreen.tlsPaddingSize': return 'TLS Padding Size'; - case 'SettingsScreen.dnsEnableRule': return 'Enable DNS Diversion rules'; - case 'SettingsScreen.dnsEnableFakeIp': return 'Enable FakeIP'; - case 'SettingsScreen.dnsEnableClientSubnet': return 'Enable ECS'; - case 'SettingsScreen.dnsEnableProxyResolveByProxy': return '[Proxy Traffic]Resolve DNS through proxy server'; - case 'SettingsScreen.dnsEnableFinalResolveByProxy': return '[final]Resolve DNS through proxy server'; - case 'SettingsScreen.dnsTestDomain': return 'Test Domain'; - case 'SettingsScreen.dnsTestDomainInvalid': return 'Invalid Domain'; - case 'SettingsScreen.dnsTypeOutbound': return 'Proxy Server'; - case 'SettingsScreen.dnsTypeDirect': return 'Direct Traffic'; - case 'SettingsScreen.dnsTypeProxy': return 'Proxy Traffic'; - case 'SettingsScreen.dnsTypeResolver': return 'DNS Server'; - case 'SettingsScreen.dnsEnableRuleTips': return 'After enabling, the domain name will select the corresponding DNS server for resolution according to the diversion rules'; - case 'SettingsScreen.dnsEnableFakeIpTips': return 'After enabling FakeIP, if you disconnect from VPN, your app may need to be restarted; this feature requires [TUN mode] to be enabled'; - case 'SettingsScreen.dnsTypeOutboundTips': return 'Domain name resolution for Proxy Server'; - case 'SettingsScreen.dnsTypeDirectTips': return 'Domain name resolution for Direct Traffic'; - case 'SettingsScreen.dnsTypeProxyTips': return 'Domain name resolution for Proxy Traffic'; - case 'SettingsScreen.dnsTypeResolverTips': return 'Domain name resolution for Other DNS Server'; - case 'SettingsScreen.dnsTypeFinalTips': return 'Domain name resolution for Other Traffic'; - case 'SettingsScreen.dnsAutoSetServer': return 'Auto Setup Server'; - case 'SettingsScreen.dnsResetServer': return 'Reset Server'; - case 'SettingsScreen.inboundDomainResolve': return 'Resolve Inbound Domain names'; - case 'SettingsScreen.privateDirect': return 'Private Network Direct connection'; - case 'SettingsScreen.inboundDomainResolveTips': return ({required Object p}) => 'Some domain names that are not configured with diversion rules need to be resolved before they can hit the IP-based diversion rules; this feature affects inbound requests to the proxy port [${p}]'; - case 'SettingsScreen.useRomoteRes': return 'Use Remote Resources'; - case 'SettingsScreen.autoSelect': return 'Auto Select'; - case 'SettingsScreen.autoSelectServerIgnorePerProxyServer': return 'Ignore [Per-Proxy] proxy server'; - case 'SettingsScreen.autoSelectServerInterval': return 'Latency Checks Interval'; - case 'SettingsScreen.autoSelectServerReTestIfNetworkUpdate': return 'Re-check Latency when Network Changes'; - case 'SettingsScreen.autoSelectServerUpdateCurrentServerAfterManualUrltest': return 'Update the Current Server after Manual Latency Check'; - case 'SettingsScreen.autoSelectServerIntervalTips': return 'The shorter the time interval, the more timely the server latency data updates, which will occupy more resources and consume more power'; - case 'SettingsScreen.autoSelectServerFavFirst': return 'Pri-Use [My Favs]'; - case 'SettingsScreen.autoSelectServerFavFirstTips': return 'If the [My Favs] list is not empty, Then use the servers in [My Favs]'; - case 'SettingsScreen.autoSelectServerFilter': return 'Filter Invalid Servers'; - case 'SettingsScreen.autoSelectServerFilterTips': return ({required Object p}) => 'Server latency checks that fail will be filtered out; if no server is available after filtering, the first [${p}] servers will be used instead'; - case 'SettingsScreen.autoSelectServerLimitedNum': return 'Maximum number of servers'; - case 'SettingsScreen.autoSelectServerLimitedNumTips': return 'Servers exceeding this number will be filtered out'; - case 'SettingsScreen.numInvalid': return 'Invalid number'; - case 'SettingsScreen.hideInvalidServer': return 'Hide Invalid Servers'; - case 'SettingsScreen.sortServer': return 'Servers Sorting'; - case 'SettingsScreen.sortServerTips': return 'Sort by latency from low to high'; - case 'SettingsScreen.selectServerHideRecommand': return 'Hide [Recommend]'; - case 'SettingsScreen.selectServerHideRecent': return 'Hide [Recently Used]'; - case 'SettingsScreen.selectServerHideFav': return 'Hide [My Favs]'; - case 'SettingsScreen.homeScreen': return 'Home Screen'; - case 'SettingsScreen.theme': return 'Theme'; - case 'SettingsScreen.myLink': return 'Shortcut Link'; - case 'SettingsScreen.myLinkInvalid': return 'Invalid URL'; - case 'SettingsScreen.autoConnectAfterLaunch': return 'Auto Connection after Launch'; - case 'SettingsScreen.hideAfterLaunch': return 'Hide window after startup'; - case 'SettingsScreen.autoSetSystemProxy': return 'Auto Set System Proxy when Connected'; - case 'SettingsScreen.disconnectWhenQuit': return 'Disconnect when App Exits'; - case 'SettingsScreen.allowBypass': return 'Allow Apps to Bypass VPN'; - case 'SettingsScreen.lanSyncTo': return 'Sync to others'; - case 'SettingsScreen.lanSyncFrom': return 'Sync from others'; - case 'SettingsScreen.lanSyncScanQRcode': return 'Scan QR code to Sync'; - case 'SettingsScreen.syncToConfirm': return 'Confirm sync to the other party?'; - case 'SettingsScreen.syncDone': return 'Sync completed'; - case 'SettingsScreen.importSuccess': return 'Import Success'; - case 'SettingsScreen.rewriteConfirm': return 'This file will overwrite the existing local configuration. Do you want to continue?'; - case 'SettingsScreen.networkShare': return 'Network Sharing'; - case 'SettingsScreen.frontProxy': return 'Per-Proxy'; - case 'SettingsScreen.frontProxyTips': return 'Data->Per-Proxy server->Proxy server->Target server'; - case 'SettingsScreen.allowOtherHostsConnect': return 'Allow Others to Connect'; - case 'SettingsScreen.allowOtherHostsConnectTips': return ({required Object sp, required Object hp}) => 'socks:${sp},http(s):${hp}'; - case 'SettingsScreen.tunAutoRoute': return 'Auto Route'; - case 'SettingsScreen.tunStrictRoute': return 'Strict Route'; - case 'SettingsScreen.tunStrictRouteTips': return 'If after turning on sharing, others cannot access this device, please try turning off this switch'; - case 'SettingsScreen.enableCluster': return 'Enable Socks/Http Proxy Cluster'; - case 'SettingsScreen.clusterAllowOtherHostsConnect': return 'Allow Others to Connect to Cluster'; - case 'SettingsScreen.clusterAllowOtherHostsConnectTips': return ({required Object hp}) => 'http://127.0.0.1:${hp}/get_proxies'; - case 'SettingsScreen.clusterAuth': return 'Proxy Cluster Authentication'; - case 'SettingsScreen.clusterConfirm': return 'Please confirm that the servers latency have been checked, and proxy services will not be created if they are not checked or checked incorrectly'; - case 'SettingsScreen.tunMode': return 'TUN Mode'; - case 'SettingsScreen.tunModeTips': return 'The TUN mode will take over all the traffic of the system [In this mode, you can leave the system proxy unenabled]'; - case 'SettingsScreen.tunModeRunAsAdmin': return 'The TUN mode requires system administrator permissions, please restart the app as an administrator'; - case 'SettingsScreen.tunStack': return 'Stack'; - case 'SettingsScreen.launchAtStartup': return 'Launch at Startup'; - case 'SettingsScreen.quitWhenSwitchSystemUser': return 'Exit App when Switch System Users'; - case 'SettingsScreen.handleScheme': return 'System Scheme Call'; - case 'SettingsScreen.portableMode': return 'Portable Mode'; - case 'SettingsScreen.portableModeDisableTips': return 'If you need to exit portable mode, please exit [karing] and manually delete the [profiles] folder in the same directory as [karing.exe]'; - case 'SettingsScreen.handleKaringScheme': return 'Handle karing:// Call'; - case 'SettingsScreen.handleClashScheme': return 'Handle clash:// Call'; - case 'SettingsScreen.handleSingboxScheme': return 'Handle sing-box:// Call'; - case 'SettingsScreen.removeSystemVPNConfig': return 'Delete system VPN configuration'; - case 'SettingsScreen.timeConnectOrDisconnect': return 'Scheduled connect/disconnect'; - case 'SettingsScreen.timeConnectOrDisconnectTips': return 'VPN must be connected to take effect; after it is turned on, [Automatic Sleep] will be disabled'; - case 'SettingsScreen.timeConnectAndDisconnectInterval': return ({required Object p}) => 'The connection/disconnection interval cannot be less than ${p} minutes'; - case 'SettingsScreen.disableFontScaler': return 'Disable Font scaling(Restart takes effect)'; - case 'SettingsScreen.autoOrientation': return 'Rotate with the screen'; - case 'SettingsScreen.restartTakesEffect': return 'Restart takes effect'; - case 'SettingsScreen.resetSettings': return 'Reset Settings'; - case 'SettingsScreen.cleanCache': return 'Cleanup Cache'; - case 'SettingsScreen.cleanCacheDone': return 'Cleanup completed'; - case 'SettingsScreen.appleTestFlight': return 'Apple TestFlight'; - case 'SettingsScreen.appleAppStore': return 'Apple AppStore'; - case 'SettingsScreen.hasNewVersion': return ({required Object p}) => 'Update Version ${p}'; - case 'SettingsScreen.follow': return 'Follow Us'; - case 'SettingsScreen.contactUs': return 'Contact Us'; - case 'SettingsScreen.rateInApp': return 'Rate Us'; - case 'SettingsScreen.rateInAppStore': return 'Rate Us in AppStore'; - case 'SpeedTestSettingsScreen.title': return 'Speed Test URL'; - case 'SpeedTestSettingsScreen.error': return 'Must be Valid https URL'; - case 'TextToQrCodeScreen.title': return 'Text To QR Code'; - case 'TextToQrCodeScreen.convert': return 'Convert'; - case 'UrlTestSettingsScreen.title': return 'Latency Checks URL'; - case 'UrlTestSettingsScreen.error': return 'Must be Valid https URL'; - case 'UserAgreementScreen.privacyFirst': return 'Your Privacy Comes First'; - case 'UserAgreementScreen.agreeAndContinue': return 'Accept & Continue'; - case 'VersionUpdateScreen.versionReady': return ({required Object p}) => 'The new version[${p}] is ready'; - case 'VersionUpdateScreen.update': return 'Restart To Update'; - case 'VersionUpdateScreen.cancel': return 'Not Now'; - case 'CommonWidget.diableAlwayOnVPN': return 'If [Always on VPN] is turned on, please turn off [Always on VPN] and try connecting again'; - case 'CommonWidget.resetPort': return 'Please change the port to another available port or close the application occupying the port.'; - case 'ServerManager.noServerAvaliable': return 'No server avaliable, Make sure the Profile Link or Profile File is valid; if your Profile comes from GitHub, please obtain the link from the [Raw] button on the page'; - case 'ServerManager.filePathCannotEmpty': return 'The file path can not be empty'; - case 'ServerManager.fileNotExist': return ({required Object p}) => 'File does not exist:${p}'; - case 'ServerManager.urlCannotEmpty': return 'Link can not be empty'; - case 'ServerManager.invalidUrl': return 'Invalid Profile Link'; - case 'ServerManager.parseFailed': return 'Parsing Profile failed'; - case 'main.tray.menuOpen': return ' Open '; - case 'main.tray.menuExit': return ' Exit '; - case 'enable': return 'Enable'; - case 'disable': return 'Disable'; - case 'prefer': return 'Prefer'; - case 'only': return 'Only'; - case 'open': return 'Open'; - case 'close': return 'Close'; - case 'quit': return 'Quit'; - case 'add': return 'Add'; - case 'remove': return 'Remove'; - case 'edit': return 'Edit'; - case 'view': return 'View'; - case 'more': return 'More'; - case 'addProfile': return 'Add Profile'; - case 'addSuccess': return 'Added successfully'; - case 'addSuccessThen': return ({required Object p}) => 'Profile generated successfully, please go to [${p}] to view'; - case 'addFailed': return ({required Object p}) => 'Add failed:${p}'; - case 'removeConfirm': return 'Are you sure to delete?'; - case 'tips': return 'Info'; - case 'copy': return 'Copy'; - case 'ok': return 'Ok'; - case 'cancel': return 'Cancel'; - case 'feedback': return 'Feedback'; - case 'faq': return 'FAQ'; - case 'download': return 'Download'; - case 'loading': return 'Loading...'; - case 'updateFailed': return ({required Object p}) => 'Update failed:${p}'; - case 'days': return 'Days'; - case 'hours': return 'Hours'; - case 'minutes': return 'Minutes'; - case 'seconds': return 'Seconds'; - case 'protocol': return 'Protocol'; - case 'search': return 'Search'; - case 'custom': return 'Custom'; - case 'connect': return 'Connect'; - case 'disconnect': return 'Disconnect'; - case 'connected': return 'Connected'; - case 'disconnected': return 'Disconnected'; - case 'connecting': return 'Connecting'; - case 'connectTimeout': return 'Connect Timeout'; - case 'timeout': return 'Timeout'; - case 'language': return 'Language'; - case 'next': return 'Next'; - case 'done': return 'Done'; - case 'apply': return 'Apply'; - case 'refresh': return 'Refresh'; - case 'retry': return 'Retry?'; - case 'none': return 'None'; - case 'reset': return 'Reset'; - case 'submit': return 'Submit'; - case 'account': return 'Account'; - case 'password': return 'Password'; - case 'required': return 'Required'; - case 'diversion': return 'Diversion'; - case 'diversionRules': return 'Diversion Rules'; - case 'diversionRulesEnable': return 'Enable [ISP] Diversion Rules'; - case 'diversionCustomGroup': return 'Custom Diversion Group'; - case 'diversionCustomGroupPreset': return 'Preset [Custom Diversion Group]'; - case 'diversionCustomGroupPresetTips': return 'Note: Enabled items will be added/overwritten to [Custom Diversion Group] and [Diversion Rules]'; - case 'diversionCustomGroupAddTips': return 'Note: After adding, you may need to manually adjust the order, otherwise the newly added diversion may not take effect'; - case 'urlTestCustomGroup': return 'Custom Proxy Group'; - case 'rulesetEnableTips': return 'Tip: After turning on the options, please go to[Diversion Rules]to set the relevant rules, otherwise they will not take effect'; - case 'ispUserAgentTips': return '[ISP] will send data of different subscription types based on [UserAgent] in [HTTP] request'; - case 'ispDiversionTips': return '[ISP] provides traffic diversion rules; [V2Ray] type subscriptions do not support traffic diversion rules'; - case 'staticIP': return 'Static IP'; - case 'other': return 'Other'; - case 'dns': return 'DNS'; - case 'url': return 'URL'; - case 'isp': return 'ISP'; - case 'tls': return 'TLS'; - case 'userAgent': return 'UserAgent'; - case 'urlInvalid': return 'Invalid URL'; - case 'outboundActionCurrentSelected': return 'Current Selected'; - case 'outboundActionUrltest': return 'Auto Select'; - case 'outboundActionDirect': return 'Direct'; - case 'outboundActionBlock': return 'Block'; - case 'routeFinal': return 'final'; - case 'rulesetGeoSite': return 'GeoSite'; - case 'rulesetGeoIp': return 'GeoIP'; - case 'rulesetAcl': return 'ACL'; - case 'iCloud': return 'iCloud'; - case 'appleTV': return 'Apple TV'; - case 'webdav': return 'Webdav'; - case 'setting': return 'Settings'; - case 'protocolSniff': return 'Protocol Sniff'; - case 'protocolSniffOverrideDestination': return 'The Sniff domain name override the connection target address'; - case 'remark': return 'Remark'; - case 'remarkCannotEmpty': return 'Remarks can not be empty'; - case 'remarkTooLong': return 'Remarks up to 32 characters'; - case 'remarkExist': return 'Remark already exists, please use another name'; - case 'domainSuffix': return 'Domain Suffix'; - case 'domain': return 'Domain'; - case 'domainKeyword': return 'Domain Keyword'; - case 'domainRegex': return 'Domain Regex'; - case 'ip': return 'IP'; - case 'port': return 'Port'; - case 'appPackage': return 'App Package Name'; - case 'processName': return 'Process Name'; - case 'processPath': return 'Process Path'; - case 'systemProxy': return 'System Proxy'; - case 'netInterfaces': return 'Net Interfaces'; - case 'netSpeed': return 'Speed'; - case 'website': return 'Website'; - case 'rule': return 'Rule'; - case 'global': return 'Global'; - case 'qrcode': return 'QR Code'; - case 'scanQrcode': return 'Scan QR Code'; - case 'scanResult': return 'Scan Result'; - case 'backupAndSync': return 'Backup and Sync'; - case 'importAndExport': return 'Import and Export'; - case 'import': return 'Import'; - case 'export': return 'Export'; - case 'termOfUse': return 'Terms of Service'; - case 'privacyPolicy': return 'Privacy & Policy'; - case 'about': return 'About'; - case 'name': return 'Name'; - case 'version': return 'Version'; - case 'notice': return 'Notice'; - case 'sort': return 'Reorder'; - case 'novice': return 'Novice Mode'; - case 'recommended': return 'Recommend'; - case 'innerError': return ({required Object p}) => 'Inner Error:${p}'; - case 'logicOperation': return 'Logic Operation'; - case 'share': return 'Share'; - case 'candidateWord': return 'Candidate Words'; - case 'keywordsOrRegx': return 'Keywords/Regular'; - case 'importFromClipboard': return 'Import From Clipboard'; - case 'exportToClipboard': return 'Export to Clipboard'; - case 'server': return 'Server'; - case 'appleTVConnectTurnOfprivateDirect': return 'Please turn on [Private network direct connection] first'; - case 'targetConnectFailed': return ({required Object p}) => 'Failed to connect to [${p}]. Please make sure the devices are in the same LAN and enable [Private Network Direct Connection]'; - case 'appleTVSync': return 'Synchronize the current core configuration to Apple TV - Karing'; - case 'appleTVSyncDone': return 'Synchronization is complete. Please go to Apple TV - Karing to start the connection/restart the connection'; - case 'appleTVRemoveCoreConfig': return 'Delete Apple TV - Karing Core Configuration'; - case 'appleTVRemoveCoreConfigDone': return 'Apple TV - Karing\'s Core Configuration deleted; VPN service disconnected'; - case 'appleTVUrlInvalid': return 'Invalid URL, please open Apple TV - Karing and scan the QR code displayed by Karing'; - case 'remoteProfileEditConfirm': return 'After the Profile is updated, the node changes will be restored. Continue?'; - case 'invalidFileType': return ({required Object p}) => 'Invalid file type:${p}'; - case 'locales.en': return 'English'; - case 'locales.zh-CN': return '简体中文'; - case 'locales.ar': return 'عربي'; - case 'locales.ru': return 'Русский'; - case 'locales.fa': return 'فارسی'; - default: return null; - } - } -} - -extension on _StringsAr { - dynamic _flatMapFunction(String path) { - switch (path) { - case 'AboutScreen.installRefer': return 'تثبيت الرجوع'; - case 'AboutScreen.versionChannel': return 'تحديث القنوات تلقائيا'; - case 'AboutScreen.disableUAReport': return 'قم بإيقاف تشغيل تقرير بيانات الإجراء'; - case 'AboutScreen.disableUAReportTip': return 'تساعدنا تقارير البيانات السلوكية على تحسين تجربة المنتج؛ ستقوم الإصدارات الأقل من الإصدار الرئيسي بإيقاف تشغيل جميع تقارير البيانات تلقائيًا (باستثناء [تنشيط التطبيق])'; - case 'AboutScreen.devOptions': return 'خيارات للمطور'; - case 'AboutScreen.enableDebugLog': return 'تمكين سجل التصحيح'; - case 'AboutScreen.viewFilsContent': return 'عرض الملفات'; - case 'AboutScreen.enablePprof': return 'يُمكَِن pprof'; - case 'AboutScreen.pprofPanel': return 'pprof لوحة'; - case 'AboutScreen.openDir': return 'فتح دليل الملف'; - case 'AboutScreen.useOriginalSBProfile': return 'استخدم تكوين صندوق الغناء الأصلي'; - case 'AddProfileByImportFromFileScreen.title': return 'استيراد ملف الملف الشخصي'; - case 'AddProfileByImportFromFileScreen.chooseFile': return 'حدد الملف'; - case 'AddProfileByImportFromFileScreen.configExist': return 'الملف الشخصي موجود بالفعل ، من فضلك لا تضيفه مرارًا وتكرارًا'; - case 'AddProfileByLinkOrContentScreen.title': return 'إضافة رابط ملف التعريف'; - case 'AddProfileByLinkOrContentScreen.updateTimerInterval': return 'الفاصل الزمني للتحديث'; - case 'AddProfileByLinkOrContentScreen.updateTimerIntervalTips': return 'لتعطيل من فضلك ضبط على:<5m'; - case 'AddProfileByLinkOrContentScreen.profileLinkContent': return 'رابط/محتوى الملف الشخصي'; - case 'AddProfileByLinkOrContentScreen.profileLinkContentHit': return 'ارتباط ملف التعريف/المحتوى [مطلوب] (دعم الدعم ، V2Ray (مدعوم الدفعة) ، خبأ ، karing ، sing-box ، shadowsocks ، روابط الملف الشخصي الفرعي)'; - case 'AddProfileByLinkOrContentScreen.subscriptionCannotEmpty': return 'لا يمكن أن يكون رابط الملف الشخصي فارغًا'; - case 'AddProfileByLinkOrContentScreen.configExist': return 'الملف الشخصي موجود بالفعل ، من فضلك لا تضيفه مرارًا وتكرارًا'; - case 'AddProfileByLinkOrContentScreen.invalidUrl': return 'رابط الملف الطويل جدًا'; - case 'AddProfileByLinkOrContentScreen.addFailedFormatException': return ({required Object p}) => 'التنسيق خاطئ ، يرجى تصحيحه وإضافته مرة أخرى:${p}'; - case 'AddProfileByLinkOrContentScreen.addFailedThenDownloadAndImport': return ({required Object p}) => 'فشلت إضافة: ${p}، يرجى محاولة تعديل [UserAgent] والمحاولة مرة أخرى، أو استخدم المتصفح الخاص بالجهاز لفتح رابط التكوين واستيراد ملف التكوين الذي تم تنزيله بواسطة المتصفح إلى هذا التطبيق'; - case 'AddProfileByLinkOrContentScreen.addFailedHandshakeException': return ({required Object p}) => 'فشلت إضافة: ${p}، يرجى فتح الوكيل أو تعديل عقدة الوكيل الحالية والمحاولة مرة أخرى'; - case 'AddProfileByScanQrcodeScanScreen.copy': return 'Copy Link'; - case 'AddProfileByScanQrcodeScanScreen.open': return 'Open Link'; - case 'AddProfileByScanQrcodeScanScreen.requestCameraPermission': return 'يرجى تمكين إذن الكاميرا'; - case 'AddProfileByScanQrcodeScanScreen.requestScreenAccess': return 'يرجى الانتقال إلى إعدادات النظام - الخصوصية والأمان - تسجيل الشاشة لإضافة أذونات لهذا التطبيق'; - case 'AddProfileByScanQrcodeScanScreen.screenshot': return 'لقطة شاشة'; - case 'AddProfileByScanQrcodeScanScreen.scanFromImage': return 'مسح من الصورة'; - case 'AddProfileByScanQrcodeScanScreen.scanNoResult': return 'فشل في تحليل الصورة ، يرجى التأكد من أن لقطة الشاشة هي رمز QR صالح'; - case 'AddProfileByScanQrcodeScanScreen.scanEmptyResult': return 'نتيجة الفحص فارغة'; - case 'AddProfileByScanQrcodeScanScreen.scanException': return ({required Object p}) => 'فشل في تحليل الصورة ، يرجى التأكد من أن لقطة الشاشة هي رمز QR صالح: ${p}'; - case 'BackupAndSyncLanSyncScreen.title': return 'LAN SYNC'; - case 'BackupAndSyncLanSyncScreen.lanSyncNotQuitTips': return 'لا تخرج من هذه الواجهة قبل اكتمال التزامن'; - case 'BackupAndSyncWebdavScreen.webdavServerUrl': return 'عنوان URL الخادم'; - case 'BackupAndSyncWebdavScreen.webdavRequired': return 'لايمكن ان يكون فارغا'; - case 'BackupAndSyncWebdavScreen.webdavLoginFailed': return 'فشل تسجيل الدخول:'; - case 'BackupAndSyncWebdavScreen.webdavListFailed': return 'فشل في الحصول على قائمة الملفات:'; - case 'DiversionGroupCustomEditScreen.invalidDomain': return ({required Object p}) => 'غير صالح [Domain]:${p}'; - case 'DiversionGroupCustomEditScreen.invalidIpCidr': return ({required Object p}) => 'غير صالح [IP Cidr]:${p}'; - case 'DiversionGroupCustomEditScreen.invalidPort': return ({required Object p}) => 'غير صالح [Port]:${p}'; - case 'DiversionGroupCustomEditScreen.invalidRuleSet': return ({required Object p}) => 'غير صالح [Rule Set]:${p}, يجب أن يكون عنوان URL عنوان URL HTTPS صالحًا وملفًا ثنائيًا مع ملحق الملف .SRS'; - case 'DiversionGroupCustomEditScreen.invalidRuleSetBuildIn': return ({required Object p}) => 'غير صالح [Rule Set(build-in)]:${p} غير صالحة، التنسيق هو geosite:xxx أو geoip:xxx أو acl:xxx، ويجب أن يكون xxx اسم قاعدة صالحًا'; - case 'DiversionGroupCustomEditScreen.setDiversionRule': return 'نصيحة: بعد الحفظ، يرجى الانتقال إلى [قواعد التحويل] لتعيين القواعد ذات الصلة، وإلا فلن تصبح سارية المفعول.'; - case 'DiversionRuleDetectScreen.title': return 'قاعدة التحويل اكتشف'; - case 'DiversionRuleDetectScreen.detect': return 'يكشف'; - case 'DiversionRuleDetectScreen.rule': return 'قاعدة:'; - case 'DiversionRuleDetectScreen.outbound': return 'مخدم بروكسي:'; - case 'DiversionRulesScreen.diversionRulesMatchTips': return 'نصيحة: حاول مطابقة القواعد من الأعلى إلى الأسفل، إذا لم تتم مطابقة أي قاعدة، استخدم [نهائي]'; - case 'DnsSettingsScreen.ispCanNotEmpty': return 'لا يمكن أن يكون ISP فارغًا'; - case 'DnsSettingsScreen.urlCanNotEmpty': return 'لا يمكن أن يكون عنوان URL فارغًا'; - case 'DnsSettingsScreen.error': return ({required Object p}) => 'نوع غير مدعوم:${p}'; - case 'DnsSettingsScreen.dnsDesc': return 'العمود الأول من بيانات التأخير هو تأخير استعلام الاتصال المباشر;\nالعمود الثاني: شغله [[حركة الوكيل]حل DNS من خلال خادم الوكيل]: بيانات التأخير هي تأخير الاستعلام الذي تم إعادة توجيهه من خلال خادم الوكيل الحالي; إذا [[حركة الوكيل]حل DNS من خلال خادم الوكيل]: بيانات التأخير هي تأخير استعلام الاتصال المباشر'; - case 'FeedbackScreen.content': return 'محتوى ردود الفعل'; - case 'FeedbackScreen.contentHit': return 'مطلوب ، ما يصل إلى 500 حرف'; - case 'FeedbackScreen.contentCannotEmpty': return 'لا يمكن أن يكون محتوى التعليقات فارغًا'; - case 'FileContentViewerScreen.title': return 'ملف محتوى الملف'; - case 'FileContentViewerScreen.chooseFile': return 'حدد الملف'; - case 'FileContentViewerScreen.clearFileContent': return 'هل أنت متأكد من مسح محتوى الملف؟'; - case 'FileContentViewerScreen.clearFileContentTips': return 'هل أنت متأكد من مسح محتوى ملف الملف الشخصي؟قد يتسبب تطهير ملف الملف الشخصي في فقدان البيانات أو وظائف التطبيق غير الطبيعية ، يرجى العمل بحذر'; - case 'HomeScreen.toSelectServer': return 'الرجاء تحديد خادم'; - case 'HomeScreen.invalidServer': return 'غير صالح ، الرجاء اختيار مرة أخرى'; - case 'HomeScreen.disabledServer': return 'معطل ، الرجاء اختيار مرة أخرى'; - case 'HomeScreen.expiredServer': return 'لا يوجد خادم متاح: قد يكون التكوين قديمًا أو معطلاً'; - case 'HomeScreen.systemProxyTips': return ({required Object sp, required Object hp}) => 'جوارب:${sp},http(s):${hp}'; - case 'HomeScreen.trafficTotal': return 'إجمالي حركة المرور'; - case 'HomeScreen.trafficProxy': return 'وكيل حركة المرور'; - case 'HomeScreen.myLinkEmpty': return 'الرجاء الإعداد [الاختصار وصلة] قبل استخدامه'; - case 'HomeScreen.deviceNoSpace': return 'مساحة غير كافيه في القرص'; - case 'HomeScreen.tooMuchServers': return ({required Object p, required Object p1}) => 'يوجد عدد كبير جدًا من الخوادم الوكيلة [${p}>${p1}]، وقد لا يكون الاتصال ممكنًا بسبب قيود ذاكرة النظام.'; - case 'LaunchFailedScreen.invalidProcess': return 'فشل التطبيق في البدء [اسم عملية غير صالح] ، يرجى إعادة تثبيت التطبيق إلى دليل منفصل'; - case 'LaunchFailedScreen.invalidProfile': return 'فشل التطبيق في البدء [فشل في الوصول إلى الملف الشخصي] ، يرجى إعادة تثبيت التطبيق'; - case 'LaunchFailedScreen.invalidVersion': return 'فشل التطبيق في بدء [إصدار غير صالح] ، يرجى إعادة تثبيت التطبيق'; - case 'LaunchFailedScreen.systemVersionLow': return 'فشل بدء تشغيل التطبيق [إصدار النظام منخفض جدًا]'; - case 'LaunchFailedScreen.startFromUNC': return 'مسار التثبيت غير صالح ، يرجى إعادة تثبيته إلى مسار صالح'; - case 'MyProfilesEditScreen.title': return 'تحرير الملف الشخصي'; - case 'MyProfilesEditScreen.urlExist': return 'عنوان URL موجود بالفعل ، يرجى استخدام عنوان URL آخر'; - case 'MyProfilesEditScreen.updateTimerInterval': return 'الفاصل الزمني للتحديث'; - case 'MyProfilesEditScreen.updateTimerIntervalTips': return 'لتعطيل يرجى تعيين:<5m'; - case 'MyProfilesEditScreen.reloadAfterProfileUpdate': return 'إعادة التحميل بعد تحديث الملف الشخصي'; - case 'MyProfilesEditScreen.testLatencyAfterProfileUpdate': return 'ابدأ اختبارات الكمون بعد التحديث تلقائيًا'; - case 'MyProfilesEditScreen.testLatencyAfterProfileUpdateTips': return 'يجب توصيل VPN ، وتمكين [إعادة التحميل بعد تحديث الملف الشخصي]'; - case 'MyProfilesEditScreen.testLatencyAutoRemove': return 'إزالة الخوادم التي تفشل تلقائيا اختبارات الكمون'; - case 'MyProfilesEditScreen.testLatencyAutoRemoveTips': return 'جرب ما يصل إلى 3 مرات'; - case 'MyProfilesMergeScreen.profilesMerge': return 'دمج الملامح'; - case 'MyProfilesMergeScreen.profilesMergeTarget': return 'ملف تعريف الهدف'; - case 'MyProfilesMergeScreen.profilesMergeSource': return 'ملفات تعريف المصدر'; - case 'MyProfilesMergeScreen.profilesMergeTips': return 'نصيحة: سيتم تجاهل تحويل ملفات تعريف المصدر'; - case 'MyProfilesScreen.title': return 'مظهر'; - case 'MyProfilesScreen.atLeastOneEnable': return 'لا يمكن تعطيله ، يرجى الاحتفاظ بملف تعريف واحد على الأقل'; - case 'NetCheckScreen.title': return 'فحص صافي'; - case 'NetCheckScreen.warn': return 'ملاحظة: نظرًا لتأثير بيئة الشبكة وقواعد التحويل ، فإن نتائج الاختبار ليست مكافئة تمامًا للنتائج الفعلية.'; - case 'NetCheckScreen.check': return 'يفحص'; - case 'NetCheckScreen.invalidDomain': return 'اسم النطاق غير صالح'; - case 'NetCheckScreen.connectivity': return 'اتصال الشبكة'; - case 'NetCheckScreen.connectivityTestIpv4AllFailed': return ({required Object p}) => 'اختبار اتصال IPv4[${p}] كل شيء فشل'; - case 'NetCheckScreen.connectivityTestIpv4Ok': return 'Ipv4 نجح الاتصال'; - case 'NetCheckScreen.connectivityTestIpv6AllFailed': return ({required Object p}) => 'Ipv6 اختبار الاتصال [${p}] كل شيء فشل ، قد لا تدعم شبكتك IPv6'; - case 'NetCheckScreen.connectivityTestIpv6Ok': return 'نجح اتصال IPv6'; - case 'NetCheckScreen.connectivityTestOk': return 'الشبكة متصلة بالإنترنت'; - case 'NetCheckScreen.connectivityTestFailed': return 'الشبكة ليست متصلة بعد بالإنترنت'; - case 'NetCheckScreen.remoteRulesetsDownloadOk': return 'تم تنزيل كل شيء بنجاح'; - case 'NetCheckScreen.remoteRulesetsDownloadNotOk': return 'التحميل أو فشل'; - case 'NetCheckScreen.outbound': return 'مخدم بروكسي'; - case 'NetCheckScreen.outboundOk': return ({required Object p}) => '[${p}] نجح الاتصال '; - case 'NetCheckScreen.outboundFailed': return ({required Object p1, required Object p2}) => '[${p1}] فشل الاتصال\nError:[${p2}]'; - case 'NetCheckScreen.dnsServer': return 'DNS الخادم'; - case 'NetCheckScreen.dnsOk': return ({required Object p1, required Object p2, required Object p3, required Object p4}) => '[${p1}]نجح استعلام DNS\nDNS قاعدة:[${p2}]\n وقت الإستجابة:[${p3} ms]\nAعنوان[${p4}]'; - case 'NetCheckScreen.dnsFailed': return ({required Object p1, required Object p2, required Object p3}) => '[${p1}]نجح استعلام DNS\n nDNS قاعدة:[${p2}]\nخطأ:[${p3}]'; - case 'NetCheckScreen.host': return 'اتصال HTTP'; - case 'NetCheckScreen.hostConnection': return ({required Object p1, required Object p2, required Object p3}) => '[${p1}]\nقاعدة التحويل:[${p2}]\nمخدم بروكسي:[${p3}]'; - case 'NetCheckScreen.hostConnectionOk': return 'نجح الاتصال'; - case 'NetCheckScreen.hostConnectionFailed': return ({required Object p}) => 'فشل الاتصال:[${p}]'; - case 'NetConnectionsFilterScreen.title': return 'تصفية الاتصالات'; - case 'NetConnectionsFilterScreen.hostIp': return 'المجال/IP'; - case 'NetConnectionsFilterScreen.app': return 'برنامج'; - case 'NetConnectionsFilterScreen.rule': return 'قاعدة'; - case 'NetConnectionsFilterScreen.chain': return 'خارج'; - case 'NetConnectionsScreen.title': return 'روابط'; - case 'NetConnectionsScreen.copyAsCSV': return 'نسخ إلى تنسيق CSV'; - case 'NetConnectionsScreen.selectType': return 'حدد نوع التحويل'; - case 'PerAppAndroidScreen.title': return 'لكل وكيل تطبيق'; - case 'PerAppAndroidScreen.whiteListMode': return 'وضع القائمة البيضاء'; - case 'PerAppAndroidScreen.whiteListModeTip': return 'عند التمكين: فقط التطبيقات التي تم فحصها هي وكلاء ؛عندما لا يتم تمكينها: فقط التطبيقات التي لم يتم فحصها هي وكلاء'; - case 'PerAppAndroidScreen.hideSystemApp': return 'إخفاء تطبيقات النظام'; - case 'PerAppAndroidScreen.hideAppIcon': return 'إخفاء أيقونة التطبيق'; - case 'PerAppAndroidScreen.enableAppQueryPermission': return 'قم بتشغيل الإذن [استعلام قائمة التطبيقات]'; - case 'QrcodeScreen.tooLong': return 'النص طويل جدًا لعرضه'; - case 'QrcodeScreen.copy': return 'نسخ الوصلة'; - case 'QrcodeScreen.open': return 'افتح الرابط'; - case 'QrcodeScreen.share': return 'شارك الرابط'; - case 'QrcodeScreen.shareImage': return 'شارك رمز الاستجابة السريعة'; - case 'RegionSettingsScreen.title': return 'الدولة او المنطقة'; - case 'RegionSettingsScreen.Regions': return ' نصيحة: يرجى تعيين بلدك أو منطقتك الحالية بشكل صحيح ، وإلا فقد يتسبب في مشاكل في تحويل الشبكة'; - case 'ServerSelectScreen.title': return 'حدد الخادم'; - case 'ServerSelectScreen.autoSelectServer': return 'تلقائي حدد الخادم بأقل زمن انتقال'; - case 'ServerSelectScreen.recentUse': return 'مستخدم حديثا'; - case 'ServerSelectScreen.myFav': return 'المفضل لدي'; - case 'ServerSelectScreen.selectLocal': return ({required Object p}) => 'الخادم المحدد هو عنوان محلي وقد لا يعمل بشكل صحيح:${p}'; - case 'ServerSelectScreen.selectRequireEnableIPv6': return 'الخادم المحدد هو عنوان IPv6 ويتطلب [تمكين IPv6]'; - case 'ServerSelectScreen.selectDisabled': return 'تم تعطيل هذا الخادم'; - case 'ServerSelectScreen.error404': return 'واجه اكتشاف الكمون خطأ ، يرجى التحقق مما إذا كان هناك تكوين مع نفس المحتوى'; - case 'SettingsScreen.ispFaq': return ({required Object p}) => 'أسئلة مكررة[${p}]'; - case 'SettingsScreen.cleanISP': return ({required Object p}) => 'ISP واضح[${p}]'; - case 'SettingsScreen.openISP': return 'فتح ISP رابط'; - case 'SettingsScreen.cleanISPNoParam': return 'مسح معلومات مزود خدمة الإنترنت '; - case 'SettingsScreen.getTranffic': return 'احصل على حركة المرور'; - case 'SettingsScreen.tutorial': return 'درس تعليمي'; - case 'SettingsScreen.commonlyUsedRulesets': return 'مجموعات القواعد شائعة الاستخدام'; - case 'SettingsScreen.howToRemoveAds': return 'كيفية إزالة الإعلانات'; - case 'SettingsScreen.htmlBoard': return 'لوحة على الانترنت'; - case 'SettingsScreen.dnsLeakDetection': return 'كشف تسرب DNS'; - case 'SettingsScreen.speedTest': return 'اختبار السرعة'; - case 'SettingsScreen.downloadProfilePreferProxy': return 'تفضل الوكيل لتنزيل الملف الشخصي'; - case 'SettingsScreen.downloadProfilePreferProxyTips': return 'إذا كان متصلاً حاليًا ، فسيتم تنزيل الملف الشخصي من خلال الوكيل المتصالح أولاً'; - case 'SettingsScreen.rulesetDirectDownlad': return 'مجموعة القواعد تحميل مباشر'; - case 'SettingsScreen.hideUnusedDiversionGroup': return 'إخفاء مجموعات التحويل غير المستخدمة'; - case 'SettingsScreen.disableISPDiversionGroup': return 'تعطيل قواعد تحويل ISP'; - case 'SettingsScreen.portSetting': return 'ميناء'; - case 'SettingsScreen.portSettingRule': return 'القاعدة القائمة'; - case 'SettingsScreen.portSettingDirectAll': return 'توجيه كل شيء'; - case 'SettingsScreen.portSettingProxyAll': return 'وكيل الكل'; - case 'SettingsScreen.portSettingControl': return 'السيطرة والمزامنة'; - case 'SettingsScreen.portSettingCluster': return 'خدمة الكتلة'; - case 'SettingsScreen.modifyPort': return 'تعديل المنفذ'; - case 'SettingsScreen.ipStrategyTips': return 'قبل التمكين ، يرجى تأكيد أن شبكتك تدعم IPv6 ، وإلا لا يمكن الوصول إلى بعض حركة المرور بشكل طبيعي.'; - case 'SettingsScreen.tunAppendHttpProxy': return 'إلحاق وكيل HTTP إلى VPN'; - case 'SettingsScreen.tunAppendHttpProxyTips': return 'ستجاوز بعض التطبيقات جهاز NIC الظاهري والاتصال مباشرة بوكيل HTTP'; - case 'SettingsScreen.tlsInsecureEnable': return 'تخطي التحقق من الشهادة'; - case 'SettingsScreen.tlsFragmentEnable': return 'تمكين تجزئة TLS'; - case 'SettingsScreen.tlsFragmentSize': return 'حجم شريحة TLS'; - case 'SettingsScreen.tlsFragmentSleep': return 'TLS النوم المجزأ'; - case 'SettingsScreen.tlsMixedCaseSNIEnable': return 'تمكين TLS الهجين SNI'; - case 'SettingsScreen.tlsPaddingEnable': return 'تمكين الحشو TLS'; - case 'SettingsScreen.tlsPaddingSize': return 'حجم الحشو TLS'; - case 'SettingsScreen.dnsEnableRule': return 'تمكين قواعد تحويل DNS'; - case 'SettingsScreen.dnsEnableFakeIp': return 'تمكين وهمية'; - case 'SettingsScreen.dnsEnableClientSubnet': return 'تمكين ECS'; - case 'SettingsScreen.dnsEnableProxyResolveByProxy': return '[حركة الوكيل] حل DNS من خلال خادم الوكيل'; - case 'SettingsScreen.dnsEnableFinalResolveByProxy': return '[نهائي] حل DNS من خلال خادم الوكيل'; - case 'SettingsScreen.dnsTestDomain': return 'مجال الاختبار'; - case 'SettingsScreen.dnsTestDomainInvalid': return 'مجال غير صالح'; - case 'SettingsScreen.dnsTypeOutbound': return 'مخدم بروكسي'; - case 'SettingsScreen.dnsTypeDirect': return 'سير مستقيم'; - case 'SettingsScreen.dnsTypeProxy': return 'حركة الوكيل'; - case 'SettingsScreen.dnsTypeResolver': return 'خادم DNS'; - case 'SettingsScreen.dnsEnableRuleTips': return 'بعد التمكين ، سيختار اسم المجال خادم DNS المقابل للدقة وفقًا لقواعد التحويل'; - case 'SettingsScreen.dnsEnableFakeIpTips': return 'بعد تمكين FakeIP، إذا تم قطع اتصال VPN، فقد يلزم إعادة تشغيل التطبيق الخاص بك؛ يجب تشغيل هذه الوظيفة [وضع TUN]'; - case 'SettingsScreen.dnsTypeOutboundTips': return 'دقة اسم المجال لخادم الوكيل'; - case 'SettingsScreen.dnsTypeDirectTips': return 'حل اسم المجال لحركة المرور المباشرة'; - case 'SettingsScreen.dnsTypeProxyTips': return 'حل اسم المجال لحركة المرور الوكيل'; - case 'SettingsScreen.dnsTypeResolverTips': return 'دقة اسم المجال لخادم DNS الآخر'; - case 'SettingsScreen.dnsTypeFinalTips': return 'حل اسم المجال لحركة المرور الأخرى'; - case 'SettingsScreen.dnsAutoSetServer': return 'إعداد الخادم تلقائيا'; - case 'SettingsScreen.dnsResetServer': return 'إعادة تعيين الخادم'; - case 'SettingsScreen.inboundDomainResolve': return 'حل أسماء النطاقات الواردة'; - case 'SettingsScreen.privateDirect': return 'اتصال مباشر بالشبكة الخاصة'; - case 'SettingsScreen.inboundDomainResolveTips': return ({required Object p}) => 'تحتاج بعض أسماء النطاقات التي لا تحتوي على قواعد تحويل تم تكوينها إلى حلها قبل أن تتمكن من الوصول إلى قواعد التحويل المستندة إلى IP؛ وتؤثر هذه الميزة على الطلبات الواردة إلى منفذ الوكيل [${p}]'; - case 'SettingsScreen.useRomoteRes': return 'استخدم الموارد البعيدة'; - case 'SettingsScreen.autoSelect': return 'اختيار آلي'; - case 'SettingsScreen.autoSelectServerIgnorePerProxyServer': return 'تجاهل الخادم الوكيل [الوكيل الأمامي].'; - case 'SettingsScreen.autoSelectServerInterval': return 'فاصل الشيكات الكمون'; - case 'SettingsScreen.autoSelectServerReTestIfNetworkUpdate': return 'إعادة اكتشاف متى تتغير الشبكة'; - case 'SettingsScreen.autoSelectServerUpdateCurrentServerAfterManualUrltest': return 'قم بتحديث الخادم الحالي بعد الكشف اليدوي عن التأخير'; - case 'SettingsScreen.autoSelectServerIntervalTips': return 'كلما كان الفاصل الزمني لاكتشاف التأخير أقصر، كلما تم تحديث بيانات تأخير الخادم في الوقت المناسب، ولكنها ستشغل المزيد من الموارد وتستهلك الكهرباء بشكل أسرع'; - case 'SettingsScreen.autoSelectServerFavFirst': return 'PRI-Use [My Favs]'; - case 'SettingsScreen.autoSelectServerFavFirstTips': return 'إذا لم تكن قائمة [Favs] فارغة ، فاستخدم الخوادم في [Favs]'; - case 'SettingsScreen.autoSelectServerFilter': return 'تصفية خوادم غير صالحة'; - case 'SettingsScreen.autoSelectServerFilterTips': return ({required Object p}) => 'سيتم تصفية حالات فشل الكشف عن تأخير الخادم؛ إذا لم يكن هناك خادم متاح بعد التصفية، فسيتم استخدام الخوادم [${p}] الأولى بدلاً من ذلك.'; - case 'SettingsScreen.autoSelectServerLimitedNum': return 'الحد الأقصى لعدد الخوادم'; - case 'SettingsScreen.autoSelectServerLimitedNumTips': return 'سيتم تصفية الخوادم التي تتجاوز هذا الرقم'; - case 'SettingsScreen.numInvalid': return 'رقم غير صالح'; - case 'SettingsScreen.hideInvalidServer': return 'إخفاء الخوادم غير الصالحة'; - case 'SettingsScreen.sortServer': return 'خوادم الفرز'; - case 'SettingsScreen.sortServerTips': return 'فرز حسب الكمون من منخفض إلى مرتفع'; - case 'SettingsScreen.selectServerHideRecommand': return 'إخفاء [يوصي]'; - case 'SettingsScreen.selectServerHideRecent': return 'إخفاء [المستخدمة مؤخرًا]'; - case 'SettingsScreen.selectServerHideFav': return 'إخفاء [المفضلة لدي]'; - case 'SettingsScreen.homeScreen': return 'الشاشة الرئيسية'; - case 'SettingsScreen.theme': return 'Tالهيم'; - case 'SettingsScreen.myLink': return 'ارتباط اختصار'; - case 'SettingsScreen.myLinkInvalid': return 'URL غير صالح'; - case 'SettingsScreen.autoConnectAfterLaunch': return 'اتصال السيارات بعد الإطلاق'; - case 'SettingsScreen.hideAfterLaunch': return 'إخفاء النافذة بعد بدء التشغيل'; - case 'SettingsScreen.autoSetSystemProxy': return 'وكيل نظام تعيين تلقائي عند الاتصال'; - case 'SettingsScreen.disconnectWhenQuit': return 'افصل عندما يخرج التطبيق'; - case 'SettingsScreen.allowBypass': return 'السماح للتطبيقات بتجاوز VPN'; - case 'SettingsScreen.lanSyncTo': return 'مزامنة للآخرين '; - case 'SettingsScreen.lanSyncFrom': return 'مزامنة من الآخرين'; - case 'SettingsScreen.lanSyncScanQRcode': return 'مسح رمز الاستجابة السريعة للمزامنة '; - case 'SettingsScreen.syncToConfirm': return 'هل تريد تأكيد المزامنة مع الطرف الآخر؟'; - case 'SettingsScreen.syncDone': return 'اكتملت المزامنة'; - case 'SettingsScreen.importSuccess': return 'استيراد نجاح '; - case 'SettingsScreen.rewriteConfirm': return 'سيقوم هذا الملف بكتابة التكوين المحلي الحالي.هل تريد الاستمرار؟'; - case 'SettingsScreen.networkShare': return 'مشاركة الشبكة'; - case 'SettingsScreen.frontProxy': return 'الوكيل الأمامي'; - case 'SettingsScreen.frontProxyTips': return 'بيانات->خادم الوكيل الأمامي->مخدم بروكسي->الخادم الهدف'; - case 'SettingsScreen.allowOtherHostsConnect': return 'اسمح للآخرين بالاتصال'; - case 'SettingsScreen.allowOtherHostsConnectTips': return ({required Object sp, required Object hp}) => 'socks:${sp},http(s):${hp}'; - case 'SettingsScreen.tunAutoRoute': return 'Auto Route'; - case 'SettingsScreen.tunStrictRoute': return 'Strict Route'; - case 'SettingsScreen.tunStrictRouteTips': return 'إذا لم يتمكن الآخرون من الوصول إلى هذا الجهاز بعد تشغيل المشاركة، فيرجى محاولة إيقاف تشغيل هذا المفتاح.'; - case 'SettingsScreen.enableCluster': return 'تمكين مجموعة الوكيل الجوارب/HTTP'; - case 'SettingsScreen.clusterAllowOtherHostsConnect': return 'السماح للآخرين بالاتصال بـ CLUSTER'; - case 'SettingsScreen.clusterAllowOtherHostsConnectTips': return ({required Object hp}) => 'http://127.0.0.1:${hp}/get_proxies'; - case 'SettingsScreen.clusterAuth': return 'مصادقة مجموعة الوكيل'; - case 'SettingsScreen.clusterConfirm': return 'يرجى التأكيد على أنه تم فحص زمن انتقال الخوادم ، ولن يتم إنشاء خدمات الوكيل إذا لم يتم فحصها أو فحصها بشكل غير صحيح'; - case 'SettingsScreen.tunMode': return 'نفق وضع'; - case 'SettingsScreen.tunModeTips': return 'سيتولى وضع TUN كل حركة مرور النظام [في هذا الوضع ، يمكنك ترك وكيل النظام غير مدقلة]'; - case 'SettingsScreen.tunModeRunAsAdmin': return 'يتطلب وضع TUN أذونات مسؤول النظام ، يرجى إعادة تشغيل التطبيق كمسؤول'; - case 'SettingsScreen.tunStack': return 'Stack'; - case 'SettingsScreen.launchAtStartup': return 'إطلاق عند بدء التشغيل'; - case 'SettingsScreen.quitWhenSwitchSystemUser': return 'خروج تطبيق عند تبديل مستخدمي النظام'; - case 'SettingsScreen.handleScheme': return 'مكالمة مخطط النظام'; - case 'SettingsScreen.portableMode': return 'الوضع المحمول'; - case 'SettingsScreen.portableModeDisableTips': return 'إذا كنت بحاجة إلى الخروج من الوضع المحمول، فيرجى الخروج من [karing] وحذف المجلد [profiles] يدويًا في نفس الدليل مثل [karing.exe]'; - case 'SettingsScreen.handleKaringScheme': return 'مقبض karing:// Call'; - case 'SettingsScreen.handleClashScheme': return 'مقبض clash:// Call'; - case 'SettingsScreen.handleSingboxScheme': return 'مقبض sing-box:// يتصل'; - case 'SettingsScreen.removeSystemVPNConfig': return 'حذف تكوين VPN النظام'; - case 'SettingsScreen.timeConnectOrDisconnect': return 'المقرر يتصل/قطع الاتصال'; - case 'SettingsScreen.timeConnectOrDisconnectTips': return 'يجب أن يكون VPN متصلاً ليصبح مفيدًا ؛بعد تشغيله ، سيتم تعطيل [النوم التلقائي]'; - case 'SettingsScreen.timeConnectAndDisconnectInterval': return ({required Object p}) => 'ال cاتصاللا يمكن أن يكون فاصل الانفصال أقل من ${p} دقائق'; - case 'SettingsScreen.disableFontScaler': return 'تعطيل تحجيم الخط(إعادة التشغيل يسري)'; - case 'SettingsScreen.autoOrientation': return 'اتبع دوران الشاشة'; - case 'SettingsScreen.restartTakesEffect': return 'إعادة التشغيل يسري'; - case 'SettingsScreen.resetSettings': return 'اعادة الضبط'; - case 'SettingsScreen.cleanCache': return 'مسح ذاكرة التخزين المؤقت'; - case 'SettingsScreen.cleanCacheDone': return 'اكتملت عملية التنظيف'; - case 'SettingsScreen.appleTestFlight': return 'Apple Testflight'; - case 'SettingsScreen.appleAppStore': return 'متجر تطبيقات Apple'; - case 'SettingsScreen.hasNewVersion': return ({required Object p}) => 'تحديث الإصدار ${p}'; - case 'SettingsScreen.follow': return 'تابعنا'; - case 'SettingsScreen.contactUs': return 'اتصل بنا'; - case 'SettingsScreen.rateInApp': return 'قيمنا'; - case 'SettingsScreen.rateInAppStore': return 'قيمنا في متجر التطبيقات'; - case 'SpeedTestSettingsScreen.title': return 'URL اختبار السرعة'; - case 'SpeedTestSettingsScreen.error': return 'يجب أن يكون عنوان URL HTTPS صالح'; - case 'TextToQrCodeScreen.title': return 'رسالة نصية إلى رمز الاستجابة السريعة'; - case 'TextToQrCodeScreen.convert': return 'يتحول'; - case 'UrlTestSettingsScreen.title': return 'عنوان URL لاكتشاف التأخير'; - case 'UrlTestSettingsScreen.error': return 'يجب أن يكون عنوان URL HTTPS صالح'; - case 'UserAgreementScreen.privacyFirst': return 'خصوصيتك تأتي أولا'; - case 'UserAgreementScreen.agreeAndContinue': return 'قبول ومتابعة'; - case 'VersionUpdateScreen.versionReady': return ({required Object p}) => 'الإصدار الجديد [${p}] جاهز'; - case 'VersionUpdateScreen.update': return 'أعد التشغيل للتحديث'; - case 'VersionUpdateScreen.cancel': return 'ليس الآن'; - case 'CommonWidget.diableAlwayOnVPN': return 'إذا تم تشغيل [Always on VPN]، فيرجى إيقاف تشغيل [Always on VPN] ومحاولة الاتصال مرة أخرى.'; - case 'CommonWidget.resetPort': return 'الرجاء تغيير المنفذ إلى منفذ آخر متاح أو إغلاق التطبيق الذي يشغل المنفذ.'; - case 'ServerManager.noServerAvaliable': return 'لا يوجد خادم متاح، يرجى التأكد من صلاحية رابط التكوين أو ملف التكوين؛ وإذا كان التكوين الخاص بك يأتي من GitHub، فيرجى الحصول على عنوان الرابط من الزر [Raw] الموجود في الصفحة'; - case 'ServerManager.filePathCannotEmpty': return 'لا يمكن أن يكون مسار الملف فارغًا'; - case 'ServerManager.fileNotExist': return ({required Object p}) => 'الملف غير موجود: ${p}'; - case 'ServerManager.urlCannotEmpty': return 'لا يمكن أن يكون الرابط فارغًا'; - case 'ServerManager.invalidUrl': return 'رابط ملف تعريف غير صالح'; - case 'ServerManager.parseFailed': return 'فشل تحليل الملف الشخصي'; - case 'main.tray.menuOpen': return ' يفتح '; - case 'main.tray.menuExit': return ' مخرج '; - case 'enable': return 'يُمكَِن'; - case 'disable': return 'إبطال'; - case 'prefer': return 'أولوية'; - case 'only': return 'فقط'; - case 'open': return 'يفتح'; - case 'close': return 'إنهاء'; - case 'quit': return 'يترك'; - case 'add': return 'اضف إليه'; - case 'remove': return 'يمسح'; - case 'edit': return 'يحرر'; - case 'view': return 'يفحص'; - case 'more': return 'أكثر'; - case 'addProfile': return 'إضافة ملف تعريف'; - case 'addSuccess': return 'اضيف بنجاح'; - case 'addSuccessThen': return ({required Object p}) => 'تم إنشاء التكوين بنجاح، يرجى الانتقال إلى [${p}] للعرض'; - case 'addFailed': return ({required Object p}) => 'إضافة فشل:${p}'; - case 'removeConfirm': return 'هل انت متأكد من الحذف؟'; - case 'tips': return 'معلومات'; - case 'copy': return 'ينسخ'; - case 'ok': return 'نعم'; - case 'cancel': return 'يلغي'; - case 'feedback': return 'تعليق'; - case 'faq': return 'أسئلة مكررة'; - case 'download': return 'تحميل'; - case 'loading': return 'تحميل...'; - case 'updateFailed': return ({required Object p}) => 'فشل التحديث:${p}'; - case 'days': return 'أيام'; - case 'hours': return 'ساعات'; - case 'minutes': return 'دقائق'; - case 'seconds': return 'ثانية'; - case 'protocol': return 'بروتوكول'; - case 'search': return 'يبحث'; - case 'custom': return 'مخصص'; - case 'connect': return 'يتصل'; - case 'disconnect': return 'قطع الاتصال'; - case 'connected': return 'متصل'; - case 'disconnected': return 'انقطع الاتصال'; - case 'connecting': return 'توصيل'; - case 'connectTimeout': return 'ربط مهلة'; - case 'timeout': return 'نفذ الوقت'; - case 'language': return 'لغة'; - case 'next': return 'التالي'; - case 'done': return 'منتهي'; - case 'apply': return 'يتقدم'; - case 'refresh': return 'ينعش'; - case 'retry': return 'إعادة المحاولة?'; - case 'none': return 'لا أحد'; - case 'reset': return 'إعادة ضبط'; - case 'submit': return 'يُقدِّم'; - case 'account': return 'حساب'; - case 'password': return 'كلمة المرور'; - case 'required': return 'مطلوب'; - case 'diversion': return 'تحويل'; - case 'diversionRules': return 'قواعد التحويل'; - case 'diversionRulesEnable': return 'تمكين قواعد تفريغ [ISP]'; - case 'diversionCustomGroup': return 'مجموعة تحويل مخصصة'; - case 'diversionCustomGroupPreset': return 'الإعداد المسبق [مجموعة تحويل مخصصة]'; - case 'diversionCustomGroupPresetTips': return 'ملاحظة: ستتم إضافة/تغطية العناصر الممكّنة إلى [مجموعة التحويل المخصصة] و[قواعد التحويل]'; - case 'diversionCustomGroupAddTips': return 'ملاحظة: قد تحتاج إلى ضبط الفرز يدويًا بعد إضافته، وإلا فإن التحويل المضاف حديثًا قد لا يسري مفعوله.'; - case 'urlTestCustomGroup': return 'مجموعة الوكيل المخصصة'; - case 'rulesetEnableTips': return 'نصيحة: بعد تشغيل الخيارات ، يرجى الانتقال إلى [قواعد التحويل] لتعيين القواعد ذات الصلة ، وإلا فلن تدخل ساري المفعول '; - case 'ispUserAgentTips': return 'سيقدم [ISP] أنواعًا مختلفة من بيانات الاشتراك بناءً على [UserAgent] في طلب [HTTP].'; - case 'ispDiversionTips': return 'قواعد التفريغ التي يوفرها [ISP]؛ لا تدعم الاشتراكات من النوع [V2Ray] قواعد التفريغ'; - case 'staticIP': return 'رقم تعريف حاسوب ثابت'; - case 'other': return 'آخر'; - case 'dns': return 'DNS'; - case 'url': return 'URL'; - case 'isp': return 'ISP'; - case 'tls': return 'TLS'; - case 'userAgent': return 'UserAgent'; - case 'urlInvalid': return 'URL غير صالح'; - case 'outboundActionCurrentSelected': return 'المحدد الحالي'; - case 'outboundActionUrltest': return 'اختيار آلي'; - case 'outboundActionDirect': return 'مباشر'; - case 'outboundActionBlock': return 'حاجز'; - case 'routeFinal': return 'أخير'; - case 'rulesetGeoSite': return 'GeoSite'; - case 'rulesetGeoIp': return 'GeoIP'; - case 'rulesetAcl': return 'ACL'; - case 'iCloud': return 'iCloud'; - case 'appleTV': return 'Apple TV'; - case 'webdav': return 'Webdav'; - case 'setting': return 'إعدادات'; - case 'protocolSniff': return 'الكشف عن البروتوكول'; - case 'protocolSniffOverrideDestination': return 'يغطي اسم المجال المكتشف عنوان هدف الاتصال'; - case 'remark': return 'ملاحظة'; - case 'remarkCannotEmpty': return 'لا يمكن أن تكون الملاحظات فارغة'; - case 'remarkTooLong': return 'ملاحظات تصل إلى 32 حرفًا'; - case 'remarkExist': return 'ملاحظة موجودة بالفعل ، يرجى استخدام اسم آخر'; - case 'domainSuffix': return 'لاحقة اسم المجال'; - case 'domain': return 'اسم النطاق'; - case 'domainKeyword': return 'الكلمات الرئيسية لاسم المجال'; - case 'domainRegex': return 'انتظام اسم المجال'; - case 'ip': return 'IP'; - case 'port': return 'ميناء'; - case 'appPackage': return 'اسم حزمة التطبيق'; - case 'processName': return 'اسم العملية'; - case 'processPath': return 'مسار العملية'; - case 'systemProxy': return 'وكيل النظام'; - case 'netInterfaces': return 'واجهات صافية'; - case 'netSpeed': return 'سرعة'; - case 'website': return 'موقع إلكتروني'; - case 'rule': return 'قاعدة'; - case 'global': return 'عالمي'; - case 'qrcode': return 'رمز الاستجابة السريعة'; - case 'scanQrcode': return 'مسح رمز الاستجابة السريعة'; - case 'scanResult': return 'نتيجة المسح'; - case 'backupAndSync': return 'النسخ الاحتياطي والمزامنة'; - case 'importAndExport': return 'استيراد وتصدير'; - case 'import': return 'يستورد'; - case 'export': return 'يصدّر'; - case 'termOfUse': return 'شرط الخدمة'; - case 'privacyPolicy': return 'سياسة الخصوصية'; - case 'about': return 'عن'; - case 'name': return 'اسم'; - case 'version': return 'إصدار'; - case 'notice': return 'يلاحظ'; - case 'sort': return 'إعادة ترتيب'; - case 'novice': return 'وضع المبتدئ'; - case 'recommended': return 'يوصي'; - case 'innerError': return ({required Object p}) => 'خطأ داخلي: ${p}'; - case 'logicOperation': return 'عملية منطقية'; - case 'share': return 'يشارك'; - case 'candidateWord': return 'كلمات المرشح'; - case 'keywordsOrRegx': return 'الكلمات الرئيسية/العادية'; - case 'importFromClipboard': return 'استيراد من الحافظة'; - case 'exportToClipboard': return 'تصدير إلى الحافظة'; - case 'server': return 'الخادم'; - case 'appleTVConnectTurnOfprivateDirect': return 'يرجى تمكين [الاتصال المباشر بالشبكة الخاصة] أولاً'; - case 'targetConnectFailed': return ({required Object p}) => 'فشل الاتصال بـ [${p}]، يرجى التأكد من وجود الجهاز في نفس الشبكة المحلية (LAN) وتمكين [الاتصال المباشر بالشبكة الخاصة]'; - case 'appleTVSync': return 'مزامنة التكوين الأساسي الحالي مع Apple TV - Karing'; - case 'appleTVSyncDone': return 'اكتملت المزامنة، برجاء الانتقال إلى Apple TV - Karing لفتح/إعادة تشغيل الاتصال'; - case 'appleTVRemoveCoreConfig': return 'إزالة Apple TV - Karing Core Configuration'; - case 'appleTVRemoveCoreConfigDone': return 'Apple TV - تم حذف الملف التعريفي الأساسي لـ Karing؛ وتم قطع اتصال خدمة VPN'; - case 'appleTVUrlInvalid': return 'عنوان URL غير صالح، يرجى فتح Apple TV - Karing، ومسح رمز QR الذي يعرضه Karing'; - case 'remoteProfileEditConfirm': return 'بعد تحديث التكوين، ستتم استعادة تعديلات العقدة. هل تريد المتابعة؟'; - case 'invalidFileType': return ({required Object p}) => 'نوع الملف غير صالح:${p}'; - case 'locales.en': return 'English'; - case 'locales.zh-CN': return '简体中文'; - case 'locales.ar': return 'عربي'; - case 'locales.ru': return 'Русский'; - case 'locales.fa': return 'فارسی'; - default: return null; - } - } -} - -extension on _StringsFa { - dynamic _flatMapFunction(String path) { - switch (path) { - case 'AboutScreen.installRefer': return 'مرجع نصب'; - case 'AboutScreen.versionChannel': return 'کانال به‌روزرسانی خودکار'; - case 'AboutScreen.disableUAReport': return 'خاموش کردن گزارش اطلاعات عملکرد'; - case 'AboutScreen.disableUAReportTip': return 'گزارش‌دهی داده‌های رفتاری به ما کمک می‌کند تا نسخه‌های پایین‌تر از نسخه اصلی را بهبود بخشیم، همه گزارش‌های داده را به‌طور خودکار خاموش می‌کند (به‌جز [فعال‌سازی برنامه]).'; - case 'AboutScreen.devOptions': return 'تنظیمات توسعه‌دهندگان'; - case 'AboutScreen.enableDebugLog': return 'فعال‌سازی گزارش اشکال‌زدایی'; - case 'AboutScreen.viewFilsContent': return 'مشاهده فایل‌ها'; - case 'AboutScreen.enablePprof': return 'فعال‌سازی pprof'; - case 'AboutScreen.pprofPanel': return 'پنل pprof'; - case 'AboutScreen.openDir': return 'بازکردن دایرکتوری فایل'; - case 'AboutScreen.useOriginalSBProfile': return 'استفاده از پروفایل اصلی سینگ‌باکس'; - case 'AddProfileByImportFromFileScreen.title': return 'وارد‌کردن فایل پروفایل'; - case 'AddProfileByImportFromFileScreen.chooseFile': return 'انتخاب فایل'; - case 'AddProfileByImportFromFileScreen.configExist': return 'پروفایل از‌قبل وجود دارد، لطفا آن را به‌طور مکرر اضافه نکنید'; - case 'AddProfileByLinkOrContentScreen.title': return 'افزودن لینک پروفایل'; - case 'AddProfileByLinkOrContentScreen.updateTimerInterval': return 'فاصله‌ی به‌روزرسانی'; - case 'AddProfileByLinkOrContentScreen.updateTimerIntervalTips': return 'برای غیرفعال‌ کردن لطفا تنظیم کنید روی:<5m'; - case 'AddProfileByLinkOrContentScreen.profileLinkContent': return 'لینک/محتوای پروفایل'; - case 'AddProfileByLinkOrContentScreen.profileLinkContentHit': return 'لینک/محتوای پروفایل [الزامی] (پشتیبانی از کلش، V2ray(پشتیبانی به‌صورت دسته‌ای)، لینک‌های پروفایل فرعی)، استش، کارینگ، سینگ‌باکس، شدوساکس، لینک‌های پروفایل فرعی)'; - case 'AddProfileByLinkOrContentScreen.subscriptionCannotEmpty': return 'لینک پروفایل نمی‌تواند خالی باشد'; - case 'AddProfileByLinkOrContentScreen.configExist': return 'پروفایل از‌قبل وجود دارد، لطفا آن را به‌طور مکرر اضافه نکنید'; - case 'AddProfileByLinkOrContentScreen.invalidUrl': return 'لینک پروفایل خیلی طولانی است'; - case 'AddProfileByLinkOrContentScreen.addFailedFormatException': return ({required Object p}) => 'فرمت اشتباه است، لطفا آن را اصلاح کرده و مجدد اضافه کنید:${p}'; - case 'AddProfileByLinkOrContentScreen.addFailedThenDownloadAndImport': return ({required Object p}) => 'افزودن نشد: ${p}، لطفاً [UserAgent] را تغییر دهید و دوباره امتحان کنید، یا از مرورگر خود دستگاه برای باز کردن پیوند پیکربندی و وارد کردن فایل پیکربندی دانلود شده توسط مرورگر به این برنامه استفاده کنید.'; - case 'AddProfileByLinkOrContentScreen.addFailedHandshakeException': return ({required Object p}) => 'اضافه کردن: ${p} ناموفق بود، لطفاً عامل را باز کنید یا گره عامل فعلی را تغییر دهید و دوباره امتحان کنید'; - case 'AddProfileByScanQrcodeScanScreen.copy': return 'کپی‌کردن لینک'; - case 'AddProfileByScanQrcodeScanScreen.open': return 'بازکردن لینک'; - case 'AddProfileByScanQrcodeScanScreen.requestCameraPermission': return 'لطفا مجوز دسترسی دوربین را فعال کنید'; - case 'AddProfileByScanQrcodeScanScreen.requestScreenAccess': return 'لطفا به تنظیمات دستگاه - حریم‌خصوصی و امنیت - ظبط صفحه بروین تا مجوز‌های این نرم‌افزار را اضافه کنید'; - case 'AddProfileByScanQrcodeScanScreen.screenshot': return 'اسکرین‌شات'; - case 'AddProfileByScanQrcodeScanScreen.scanFromImage': return 'اسکن از عکس'; - case 'AddProfileByScanQrcodeScanScreen.scanNoResult': return 'تجزیه عکس ناموفق بود، لطفا مطمعن شوید اسکرین‌شات یک کدQR معتبر است'; - case 'AddProfileByScanQrcodeScanScreen.scanEmptyResult': return 'نتیجه اسکن خالی است'; - case 'AddProfileByScanQrcodeScanScreen.scanException': return ({required Object p}) => 'تجزیه عکس ناموفق بود، لطفا مطمعن شوید اسکرین‌شات یک کدQR معتبر است: ${p}'; - case 'BackupAndSyncLanSyncScreen.title': return 'LAN Sync'; - case 'BackupAndSyncLanSyncScreen.lanSyncNotQuitTips': return 'قبل از تکمیل همگام‌سازی از این قسمت خارج نشوید'; - case 'BackupAndSyncWebdavScreen.webdavServerUrl': return 'آدرس URL سرور'; - case 'BackupAndSyncWebdavScreen.webdavRequired': return 'نمی‌تواند خالی باشد'; - case 'BackupAndSyncWebdavScreen.webdavLoginFailed': return 'ورود ناموفق بود:'; - case 'BackupAndSyncWebdavScreen.webdavListFailed': return 'دریافت لیست فایل ناموفق بود:'; - case 'DiversionGroupCustomEditScreen.invalidDomain': return ({required Object p}) => 'نامعتبر [Domain]:${p}'; - case 'DiversionGroupCustomEditScreen.invalidIpCidr': return ({required Object p}) => 'نامعتبر [IP Cidr]:${p}'; - case 'DiversionGroupCustomEditScreen.invalidPort': return ({required Object p}) => 'نامعتبر [Port]:${p}'; - case 'DiversionGroupCustomEditScreen.invalidRuleSet': return ({required Object p}) => 'نامعتبر [Rule Set]:${p} باید URL یک URL معتبر https باشد و یک فایل دودویی(binary) با پسوند فایل .srs/.json باشد'; - case 'DiversionGroupCustomEditScreen.invalidRuleSetBuildIn': return ({required Object p}) => 'نامعتبر [Rule Set(build-in)]:${p} نامعتبر است، قالب geosite:xxx یا geoip:xxx یا acl:xxx است و xxx باید یک نام قانون معتبر باشد'; - case 'DiversionGroupCustomEditScreen.setDiversionRule': return 'راهنمایی: پس‌از ذخیره کردن لطفا به [قوانین انحراف] رفته و قوانین مربوط زا تنظیم کنید؛ درغیراین صورت اعمال نخواهند شد'; - case 'DiversionRuleDetectScreen.title': return 'کشف قانون انحراف'; - case 'DiversionRuleDetectScreen.detect': return 'کشف'; - case 'DiversionRuleDetectScreen.rule': return 'قانون:'; - case 'DiversionRuleDetectScreen.outbound': return 'سرور پروکسی:'; - case 'DiversionRulesScreen.diversionRulesMatchTips': return 'نکته: سعی کنید قوانین را از بالا به پایین مطابقت دهید، از [نهایی] استفاده کنید.'; - case 'DnsSettingsScreen.ispCanNotEmpty': return 'ISP نمی‌تواند خالی باشد'; - case 'DnsSettingsScreen.urlCanNotEmpty': return 'URL نمی‌تواند خالی باشد'; - case 'DnsSettingsScreen.error': return ({required Object p}) => 'نوع پشتیبانی نشده:${p}'; - case 'DnsSettingsScreen.dnsDesc': return 'ستون اول داده‌های تأخیر، تأخیر ارتباط مستقیم است؛\nستون دوم: روشن کردن [[ترافیک پروکسی] برای حل و فصل DNS از طریق سرور پراکسی]: داده‌های تأخیر، تأخیر درخواست ارسال شده از طریق سرور پراکسی فعلی است [[ترافیک پروکسی] روشن نیست، از طریق سرور پروکسی DNS را حل می‌کند]: داده‌های تأخیر تأخیر درخواست اتصال مستقیم است'; - case 'FeedbackScreen.content': return 'محتوای بازخورد'; - case 'FeedbackScreen.contentHit': return 'الزامی، تا 500 حرف'; - case 'FeedbackScreen.contentCannotEmpty': return 'محتوای بازخورد نمی‌تواند خالی باشد'; - case 'FileContentViewerScreen.title': return 'نمایش دهنده محتوای فایل'; - case 'FileContentViewerScreen.chooseFile': return 'انتخاب فایل'; - case 'FileContentViewerScreen.clearFileContent': return 'آیا از پاکسازی محتوای فایل اطمینان دارید؟'; - case 'FileContentViewerScreen.clearFileContentTips': return 'آیا از پاکسازی محتوای فایل پروفایل اطمینان دارید؟ پاکسازی محتوای فایل پروفایل ممکن است باعث از دست رفتن داده یا عملیات غیرعادی نرم‌افزار شود؛ لطفا با احتیاط عمل کنید.'; - case 'HomeScreen.toSelectServer': return 'لطفا یک سرور انتخاب کنید'; - case 'HomeScreen.invalidServer': return 'نامعتبر است، لطفا مجدد انتخاب کنید'; - case 'HomeScreen.disabledServer': return 'غیرفعال است، لطفا مجدد انتخاب کنید'; - case 'HomeScreen.expiredServer': return 'هیچ سروری در دسترس نیست: ممکن است پیکربندی قدیمی یا غیرفعال باشد'; - case 'HomeScreen.systemProxyTips': return ({required Object sp, required Object hp}) => 'socks:${sp},http(s):${hp}'; - case 'HomeScreen.trafficTotal': return 'کل ترافیک'; - case 'HomeScreen.trafficProxy': return 'ترافیک پروکسی'; - case 'HomeScreen.myLinkEmpty': return 'لطفا قبل‌از استفاده [لینک میان‌بر] را راه‌اندازی کنید'; - case 'HomeScreen.deviceNoSpace': return 'فضای خالی کافی ندارید'; - case 'HomeScreen.tooMuchServers': return ({required Object p, required Object p1}) => 'تعداد زیادی سرور پروکسی [${p}>${p1}] وجود دارد و ممکن است به دلیل محدودیت حافظه سیستم، اتصال امکان پذیر نباشد.'; - case 'LaunchFailedScreen.invalidProcess': return 'اجرای نرم‌افزار ناموفق بود [نام‌ اجرایی پروسه نامعتبر]، لطفا مجدد نرم‌افزار را در دایرکتوری دیگری نصب کنید'; - case 'LaunchFailedScreen.invalidProfile': return 'اجرای نرم‌افزار ناموفق بود [دسترسی به پروفایل ناموفق بود]، لطفا مجدد نرم افزار را نصب کنید'; - case 'LaunchFailedScreen.invalidVersion': return 'اجرای نرم‌افزار ناموفق بود [ورژن نامعتبر]، لطفا مجدد نرم‌افزار را نصب کنید'; - case 'LaunchFailedScreen.systemVersionLow': return 'راه اندازی برنامه ناموفق بود [نسخه سیستم خیلی کم است]'; - case 'LaunchFailedScreen.startFromUNC': return 'مسیر نصب نامعتبر است، لطفا مجدد در مسیر معتبر نصب کنید'; - case 'MyProfilesEditScreen.title': return 'ویرایش پروفایل'; - case 'MyProfilesEditScreen.urlExist': return 'آدرس URL از‌قبل وجود دارد، لطفا از URL دیگری استفاده کنید'; - case 'MyProfilesEditScreen.updateTimerInterval': return 'فاصله‌ی به‌روزرسانی'; - case 'MyProfilesEditScreen.updateTimerIntervalTips': return 'برای غیرفعال‌ کردن لطفا تنظیم کنید روی:<5m'; - case 'MyProfilesEditScreen.reloadAfterProfileUpdate': return 'بارگذاری مجدد پس‌از به‌روزرسانی پروفایل'; - case 'MyProfilesEditScreen.testLatencyAfterProfileUpdate': return 'شروع تست تاخیر پس‌از به‌روزرسانی خودکار پروفایل'; - case 'MyProfilesEditScreen.testLatencyAfterProfileUpdateTips': return 'وی‌پی‌ان باید روشن و [بارگذاری مجدد پس‌از به‌روزرسانی پروفایل] فعال باشد'; - case 'MyProfilesEditScreen.testLatencyAutoRemove': return 'خودکار سرورهای ناموفق در تست تاخیر را حذف کن'; - case 'MyProfilesEditScreen.testLatencyAutoRemoveTips': return 'تا سه بار امتحان کنید'; - case 'MyProfilesMergeScreen.profilesMerge': return 'ادغام پروفایل‌ها'; - case 'MyProfilesMergeScreen.profilesMergeTarget': return 'پروفایل هدف'; - case 'MyProfilesMergeScreen.profilesMergeSource': return 'پروفایل مرجع'; - case 'MyProfilesMergeScreen.profilesMergeTips': return 'راهنمایی: انحراف پروفایل مرجع حذف می‌شود'; - case 'MyProfilesScreen.title': return 'پروفایل‌ها'; - case 'MyProfilesScreen.atLeastOneEnable': return 'نمی‌تواند غیرغعال شود، لطفا حداقل یک پروفایل را فعال نگه دارید'; - case 'NetCheckScreen.title': return 'بررسی شبکه'; - case 'NetCheckScreen.warn': return 'توجه: به دلیل تأثیر محیط شبکه و قوانین انحراف، نتایج آزمون کاملاً معادل نتایج واقعی نیست.'; - case 'NetCheckScreen.check': return 'بررسی'; - case 'NetCheckScreen.invalidDomain': return 'نام دامنه نامعتبر'; - case 'NetCheckScreen.connectivity': return 'اتصال شبکه'; - case 'NetCheckScreen.connectivityTestIpv4AllFailed': return ({required Object p}) => 'تست اتصال Ipv4 همه‌ی [${p}] ناموفق بودند'; - case 'NetCheckScreen.connectivityTestIpv4Ok': return 'اتصال Ipv4 موفق بود'; - case 'NetCheckScreen.connectivityTestIpv6AllFailed': return ({required Object p}) => 'تست اتصال Ipv6 همه‌ی [${p}] ناموفق بودند، شاید شبکه شما از Ipv6 پشتیبانی نکند'; - case 'NetCheckScreen.connectivityTestIpv6Ok': return 'اتصال Ipv6 موفق بود'; - case 'NetCheckScreen.connectivityTestOk': return 'شبکه به اینترنت متصل است'; - case 'NetCheckScreen.connectivityTestFailed': return 'شبکه هنوز به اینترنت متصل نشده'; - case 'NetCheckScreen.remoteRulesetsDownloadOk': return 'همه با موفقیت دانلود شدند'; - case 'NetCheckScreen.remoteRulesetsDownloadNotOk': return 'دانلود شد یا ناموفق بود'; - case 'NetCheckScreen.outbound': return 'سرور پروکسی'; - case 'NetCheckScreen.outboundOk': return ({required Object p}) => '[${p}] اتصال موفق بود'; - case 'NetCheckScreen.outboundFailed': return ({required Object p1, required Object p2}) => '[${p1}] اتصال ناموفق \nارور:[${p2}]'; - case 'NetCheckScreen.dnsServer': return 'سرور دی‌ان‌اس'; - case 'NetCheckScreen.dnsOk': return ({required Object p1, required Object p2, required Object p3, required Object p4}) => '[${p1}]DNS query succeeded\nDNS Rule: درخواست دی‌ان‌اس موفق بود\nقانون دی‌ان‌اس: [${p2}]\nتاخیر: [${p3} ms]\nآدرس [${p4}]'; - case 'NetCheckScreen.dnsFailed': return ({required Object p1, required Object p2, required Object p3}) => '[${p1}]جستجوی DNS موفق بود\nقانون DNS: [${p2}]\nخطا:[${p3}]'; - case 'NetCheckScreen.host': return 'اتصال HTTP'; - case 'NetCheckScreen.hostConnection': return ({required Object p1, required Object p2, required Object p3}) => '[${p1}]\nقانون انحراف: [${p2}]\nسرور پروکسی: [${p3}]'; - case 'NetCheckScreen.hostConnectionOk': return 'اتصال موفق شد'; - case 'NetCheckScreen.hostConnectionFailed': return ({required Object p}) => 'ارتباط ناموفق بود:[${p}]'; - case 'NetConnectionsFilterScreen.title': return 'فیلتر اتصال‌ها'; - case 'NetConnectionsFilterScreen.hostIp': return 'دامنه/آی‌پی'; - case 'NetConnectionsFilterScreen.app': return 'نرم‌افزار'; - case 'NetConnectionsFilterScreen.rule': return 'قانون'; - case 'NetConnectionsFilterScreen.chain': return 'Outbound'; - case 'NetConnectionsScreen.title': return 'اتصال‌ها'; - case 'NetConnectionsScreen.copyAsCSV': return 'در فرمت CAV کپی شد'; - case 'NetConnectionsScreen.selectType': return 'انتخاب نوع انحراف'; - case 'PerAppAndroidScreen.title': return 'پروکسی به‌تفکیک برنامه'; - case 'PerAppAndroidScreen.whiteListMode': return 'حالت لیست سفید'; - case 'PerAppAndroidScreen.whiteListModeTip': return 'وقتی فعال باشد: فقط برنامه‌هایی که انتخاب شده‌اند پروکسی می‌شوند؛ وقتی فعال نباشد: فقط برنامه‌هایی که انتخاب نشده‌اند پروکسی می‌شوند'; - case 'PerAppAndroidScreen.hideSystemApp': return 'برنامه های سیستم را مخفی کنید'; - case 'PerAppAndroidScreen.hideAppIcon': return 'پنهان کردن نماد برنامه'; - case 'PerAppAndroidScreen.enableAppQueryPermission': return 'مجوز [درخواست لیست نرم‌افزار] را روشن کنید'; - case 'QrcodeScreen.tooLong': return 'متن برای نمایش خیلی طولانی است'; - case 'QrcodeScreen.copy': return 'کپی‌کردن لینک'; - case 'QrcodeScreen.open': return 'بازکردن لینک'; - case 'QrcodeScreen.share': return 'اشتراک لینک'; - case 'QrcodeScreen.shareImage': return 'اشتراک کدQR'; - case 'RegionSettingsScreen.title': return 'کشور یا منطقه'; - case 'RegionSettingsScreen.Regions': return 'راهنمایی: لطفا کشور یا منطقه فعلی خود را انتخاب کنید درغیراین‌صورت ممکن‌است باعث مشکلات انحراف شبکه شود'; - case 'ServerSelectScreen.title': return 'انتخاب سرور'; - case 'ServerSelectScreen.autoSelectServer': return 'خودکار سرور با کمترین تاخیر را انتخاب کن'; - case 'ServerSelectScreen.recentUse': return 'اخیرا استفاده‌شده'; - case 'ServerSelectScreen.myFav': return 'علاقه‌مندی‌های من'; - case 'ServerSelectScreen.selectLocal': return ({required Object p}) => 'سرور انتخاب شده یک آدرس محلی است و شاید به درستی عمل نکند :${p}'; - case 'ServerSelectScreen.selectRequireEnableIPv6': return 'سرور انتخاب شده یک آدرس IPv6 است و نیاز به [فعال‌سازی IPv6] دارد'; - case 'ServerSelectScreen.selectDisabled': return 'این سرور غیرفعال شده است'; - case 'ServerSelectScreen.error404': return 'تشخیص تاخیر با یک اخطار مواجه شده‌است، لطفا بررسی کنید که کانفیگی با محتویات یکسان وجود دارد یا خیر'; - case 'SettingsScreen.ispFaq': return ({required Object p}) => 'سوالات متداول[${p}]'; - case 'SettingsScreen.cleanISP': return ({required Object p}) => 'پاک‌سازی ISP [${p}]'; - case 'SettingsScreen.openISP': return 'بازکردن لینک ISP'; - case 'SettingsScreen.cleanISPNoParam': return 'پاک‌سازی اطلاعات ISP'; - case 'SettingsScreen.getTranffic': return 'دریافت ترافیک'; - case 'SettingsScreen.tutorial': return 'آموزش'; - case 'SettingsScreen.commonlyUsedRulesets': return 'قوانین رایج'; - case 'SettingsScreen.howToRemoveAds': return 'نحوه حذف تبلیغات'; - case 'SettingsScreen.htmlBoard': return 'پنل آنلاین'; - case 'SettingsScreen.dnsLeakDetection': return 'تشخیص نشت DNS'; - case 'SettingsScreen.speedTest': return 'تست سرعت'; - case 'SettingsScreen.downloadProfilePreferProxy': return 'برای دانلود پروفایل پروکسی را ترجیح بده'; - case 'SettingsScreen.downloadProfilePreferProxyTips': return 'اگر اکنون متصل هستین، پروفایل ابتدا از پروکسی متصل دانلود می‌شود'; - case 'SettingsScreen.rulesetDirectDownlad': return 'دانلود مستقیم مجموعه قوانین'; - case 'SettingsScreen.hideUnusedDiversionGroup': return 'مخفی‌کردن گروه‌های انحراف به‌کار نرفته'; - case 'SettingsScreen.disableISPDiversionGroup': return 'قوانین انحراف ISP را غیرفعال کنید'; - case 'SettingsScreen.portSetting': return 'پورت'; - case 'SettingsScreen.portSettingRule': return 'قانون محور'; - case 'SettingsScreen.portSettingDirectAll': return 'مستقیم‌شدن همه'; - case 'SettingsScreen.portSettingProxyAll': return 'پروکسی‌شدن همه'; - case 'SettingsScreen.portSettingControl': return 'کنترل و همگام‌سازی'; - case 'SettingsScreen.portSettingCluster': return 'سرویس کلاستر'; - case 'SettingsScreen.modifyPort': return 'اصلاح پورت'; - case 'SettingsScreen.ipStrategyTips': return 'قبل‌از فعال‌سازی لطفا مطمعن شوید شبکه شما از IPv6 پشتیبانی می‌کند، وگرنه برخی ترافیک‌ها نمی‌توانند به‌صورت نرمال دردسترس باشند'; - case 'SettingsScreen.tunAppendHttpProxy': return 'پیوست دادن پروکسی HTTP به وی‌پی‌ان'; - case 'SettingsScreen.tunAppendHttpProxyTips': return 'برخی نرم‌افزار‌ها از کارت شبکه مجازی رد میشوند و مستقیم به پروکسی HTTP متصل می‌شوند'; - case 'SettingsScreen.tlsInsecureEnable': return 'رد شدن از تأیید گواهی'; - case 'SettingsScreen.tlsFragmentEnable': return 'بخش بندی TLS را فعال کنید'; - case 'SettingsScreen.tlsFragmentSize': return 'اندازه بخش TLS'; - case 'SettingsScreen.tlsFragmentSleep': return 'خواب بخش‌بندی شده TLS'; - case 'SettingsScreen.tlsMixedCaseSNIEnable': return 'TLS ترکیبی SNI را فعال کنید'; - case 'SettingsScreen.tlsPaddingEnable': return 'فعال کردن TLS Padding'; - case 'SettingsScreen.tlsPaddingSize': return 'اندازه پد TLS'; - case 'SettingsScreen.dnsEnableRule': return 'فعال‌سازی قوانین انحراف دی‌ان‌اس'; - case 'SettingsScreen.dnsEnableFakeIp': return 'فعال‌سازی آی‌پی جعلی'; - case 'SettingsScreen.dnsEnableClientSubnet': return 'ECS را فعال کنید'; - case 'SettingsScreen.dnsEnableProxyResolveByProxy': return 'دی‌ان‌اس را از [ترافیک پروکسی] سرور پروکسی عبور می‌دهد'; - case 'SettingsScreen.dnsEnableFinalResolveByProxy': return 'دی‌ان‌اس را از سرور پروکسی [نهایی] عبور می‌دهد'; - case 'SettingsScreen.dnsTestDomain': return 'تست دامنه'; - case 'SettingsScreen.dnsTestDomainInvalid': return 'دامنه نامعتبر'; - case 'SettingsScreen.dnsTypeOutbound': return 'سرور پروکسی'; - case 'SettingsScreen.dnsTypeDirect': return 'ترافیک مستقیم'; - case 'SettingsScreen.dnsTypeProxy': return 'ترافیک پروکسی'; - case 'SettingsScreen.dnsTypeResolver': return 'سرور دی‌ان‌اس'; - case 'SettingsScreen.dnsEnableRuleTips': return 'بعد از فعال‌سازی نام دامنه، سرور دی‌ان‌اس مربوط را بر اساس قوانین انحراف برای عبور انتخاب می‌کند'; - case 'SettingsScreen.dnsEnableFakeIpTips': return 'پس از فعال کردن FakeIP، اگر اتصال VPN قطع شود، ممکن است برنامه شما نیاز به راه اندازی مجدد داشته باشد [حالت TUN].'; - case 'SettingsScreen.dnsTypeOutboundTips': return 'سامانه نام دامنه (DNS) برای سرور پروکسی'; - case 'SettingsScreen.dnsTypeDirectTips': return 'سامانه نام دامنه (DNS) برای ترافیک مستقیم'; - case 'SettingsScreen.dnsTypeProxyTips': return 'سامانه نام دامنه (DNS) برای ترافیک پروکسی'; - case 'SettingsScreen.dnsTypeResolverTips': return 'سامانه نام دامنه (DNS) برای بقیه سرور دی‌ان‌اس'; - case 'SettingsScreen.dnsTypeFinalTips': return 'سامانه نام دامنه (DNS) برای بقیه ترافیک'; - case 'SettingsScreen.dnsAutoSetServer': return 'به طور خودکار سرور را راه اندازی کنید'; - case 'SettingsScreen.dnsResetServer': return 'بازنشانی سرور'; - case 'SettingsScreen.inboundDomainResolve': return 'حل نام دامنه های ورودی'; - case 'SettingsScreen.privateDirect': return 'اتصال مستقیم شبکه خصوصی'; - case 'SettingsScreen.inboundDomainResolveTips': return ({required Object p}) => 'برخی از نام‌های دامنه بدون قوانین انحراف پیکربندی شده باید حل و فصل شوند تا بتوانند قوانین انحراف مبتنی بر IP را تحت تأثیر قرار دهند [${p}].'; - case 'SettingsScreen.useRomoteRes': return 'از منابع راه‌دور استفاده کنید'; - case 'SettingsScreen.autoSelect': return 'انتخاب خودکار'; - case 'SettingsScreen.autoSelectServerIgnorePerProxyServer': return 'سرور پروکسی [پراکسی جلو] را نادیده بگیرید'; - case 'SettingsScreen.autoSelectServerInterval': return 'بازه زمانی بررسی تاخیر'; - case 'SettingsScreen.autoSelectServerReTestIfNetworkUpdate': return 'شناسایی مجدد زمانی که شبکه تغییر می کند'; - case 'SettingsScreen.autoSelectServerUpdateCurrentServerAfterManualUrltest': return 'سرور فعلی را پس از تشخیص تأخیر دستی به روز کنید'; - case 'SettingsScreen.autoSelectServerIntervalTips': return 'هرچه فاصله تشخیص تاخیر کمتر باشد، داده های تاخیر سرور به موقع به روز می شود، اما منابع بیشتری را اشغال می کند و برق را سریعتر مصرف می کند'; - case 'SettingsScreen.autoSelectServerFavFirst': return 'اولویت استفاده از [علاقه‌مندی‌های من]'; - case 'SettingsScreen.autoSelectServerFavFirstTips': return 'اگر لیست [علاقه‌مندی‌های من] خالی نبود از سرور‌های داخل [علاقه‌مندی‌های من] استفاده کن'; - case 'SettingsScreen.autoSelectServerFilter': return 'فیلترکردن سرور‌های نامعتبر'; - case 'SettingsScreen.autoSelectServerFilterTips': return ({required Object p}) => 'اگر بعد از فیلتر کردن هیچ سروری در دسترس نباشد، از اولین سرورهای [${p}] استفاده خواهد شد.'; - case 'SettingsScreen.autoSelectServerLimitedNum': return 'حداکثر تعداد سرور'; - case 'SettingsScreen.autoSelectServerLimitedNumTips': return 'سرورهای بیش از این تعداد فیلتر خواهند شد'; - case 'SettingsScreen.numInvalid': return 'عدد نامعتبر'; - case 'SettingsScreen.hideInvalidServer': return 'مخفی‌کردن سرور‌های نامعتبر'; - case 'SettingsScreen.sortServer': return 'مرتب‌سازی سرور'; - case 'SettingsScreen.sortServerTips': return 'مرتب‌سازی براساس تاخیر از کم به زیاد'; - case 'SettingsScreen.selectServerHideRecommand': return 'مخفی‌کردن [پیشنهادی]'; - case 'SettingsScreen.selectServerHideRecent': return '‌ مخفی‌کردن [اخیرا استفاده‌شده]'; - case 'SettingsScreen.selectServerHideFav': return 'مخفی‌کردن [علاقه‌مندی‌های من]'; - case 'SettingsScreen.homeScreen': return 'صفحه‌ خانه'; - case 'SettingsScreen.theme': return 'تِم'; - case 'SettingsScreen.myLink': return 'لینک میان‌بر'; - case 'SettingsScreen.myLinkInvalid': return 'URL نامعتبر'; - case 'SettingsScreen.autoConnectAfterLaunch': return 'اتصال خودکار پس‌از راه‌اندازی'; - case 'SettingsScreen.hideAfterLaunch': return 'پنهان کردن پنجره پس از راه اندازی'; - case 'SettingsScreen.autoSetSystemProxy': return 'تنظیم خودکار حالت پروکسی سیستم پس‌از اتصال'; - case 'SettingsScreen.disconnectWhenQuit': return 'قطع اتصال هنگام خروج از نرم‌افزار'; - case 'SettingsScreen.allowBypass': return 'به برنامه‌ها اجازه دهید VPN را دور بزنند'; - case 'SettingsScreen.lanSyncTo': return 'همگام‌سازی با دیگران'; - case 'SettingsScreen.lanSyncFrom': return 'همگام‌سازی از دیگران'; - case 'SettingsScreen.lanSyncScanQRcode': return 'اسکن کدQR و همگام‌سازی'; - case 'SettingsScreen.syncToConfirm': return 'همگام سازی را با طرف مقابل تأیید می کنید؟'; - case 'SettingsScreen.syncDone': return 'همگام سازی تکمیل شد'; - case 'SettingsScreen.importSuccess': return 'افزودن موفق بود'; - case 'SettingsScreen.rewriteConfirm': return 'این فایل کانفیگ‌های محلی موجود را بازنویسی می‌کند. آیا می‌خواهید ادامه بدین؟'; - case 'SettingsScreen.networkShare': return 'اشتراک‌گذاری شبکه'; - case 'SettingsScreen.frontProxy': return 'پروکسی جلو'; - case 'SettingsScreen.frontProxyTips': return 'داده‌ها->سرور پروکسی جلو->سرور پروکسی->سرور هدف'; - case 'SettingsScreen.allowOtherHostsConnect': return 'اجازه اتصال دیگران'; - case 'SettingsScreen.allowOtherHostsConnectTips': return ({required Object sp, required Object hp}) => 'socks:${sp},http(s):${hp}'; - case 'SettingsScreen.tunAutoRoute': return 'Auto Route'; - case 'SettingsScreen.tunStrictRoute': return 'Strict Route'; - case 'SettingsScreen.tunStrictRouteTips': return 'اگر پس از روشن کردن اشتراک‌گذاری، دیگران نمی‌توانند به این دستگاه دسترسی داشته باشند، لطفاً این سوئیچ را خاموش کنید.'; - case 'SettingsScreen.enableCluster': return 'فعال‌سازی پروکسی Socks/Http خوشه‌ای'; - case 'SettingsScreen.clusterAllowOtherHostsConnect': return 'اجازه اتصال دیگران به خوشه'; - case 'SettingsScreen.clusterAllowOtherHostsConnectTips': return ({required Object hp}) => 'http://127.0.0.1:${hp}/get_proxies'; - case 'SettingsScreen.clusterAuth': return 'احراز هویت خوشه پروکسی'; - case 'SettingsScreen.clusterConfirm': return 'لطفا مطمعن شوید تاخیر سرورها بررسی شده و درصورتی‌که بررسی نشده‌باشند یا اشتباه بررسی شده‌باشند سرویس پروکسی ساخته نمی‌شود'; - case 'SettingsScreen.tunMode': return 'حالت TUN'; - case 'SettingsScreen.tunModeTips': return 'حالت TUN تمام ترافیک سیستم را تحت کنترل خواهد گرفت [دراین حالت می‌توانید پروکسی سیستم را غیرفعال نگه‌ دارید)'; - case 'SettingsScreen.tunModeRunAsAdmin': return 'حالت TUN نیازمند مجوز مدیر سیستم می‌باشد لطفا نرم‌افزار را مجدد با حالت مدیر (administrator) راه‌اندازی کنید'; - case 'SettingsScreen.tunStack': return 'Stack'; - case 'SettingsScreen.launchAtStartup': return 'اجرا در راه‌اندازی'; - case 'SettingsScreen.quitWhenSwitchSystemUser': return 'خروج از نرم‌افزار هنگام تعویض کاربران سیستم'; - case 'SettingsScreen.handleScheme': return 'فراخوانی Scheme سیستم'; - case 'SettingsScreen.portableMode': return 'حالت قابل‌حمل'; - case 'SettingsScreen.portableModeDisableTips': return 'اگر نیاز دارین از حالت قابل‌حمل خارج شوید لطفا از [Karing] خارج شده و به‌صورت دستی پوشه [Profiles] هم مسیر با فایل [karing.exe] را حذف کنید'; - case 'SettingsScreen.handleKaringScheme': return 'رسیدگی به ندای karing://'; - case 'SettingsScreen.handleClashScheme': return 'رسیدگی به‌ ندای clash://'; - case 'SettingsScreen.handleSingboxScheme': return 'رسیدگی به ندای sing-box://'; - case 'SettingsScreen.removeSystemVPNConfig': return 'حذف پیکربندی وی‌پی‌ان سیستم'; - case 'SettingsScreen.timeConnectOrDisconnect': return 'اتصال/قطع اتصال برنامه‌ریزی شده'; - case 'SettingsScreen.timeConnectOrDisconnectTips': return 'برای اعمال شدن وی‌پی‌ان باید متصل باشد. پس‌از روشن‌شدن [خواب خودکار] غیرفعال می‌شود'; - case 'SettingsScreen.timeConnectAndDisconnectInterval': return ({required Object p}) => 'The connection/disconnection interval cannot be less than ${p} minutes'; - case 'SettingsScreen.disableFontScaler': return 'غیرفعال‌سازی مقیاس‌بندی فونت(با راه‌اندازی مجدد اعمال می‌شود)'; - case 'SettingsScreen.autoOrientation': return 'چرخش صفحه را دنبال کنید'; - case 'SettingsScreen.restartTakesEffect': return 'با راه‌اندازی مجدد اعمال می‌شود'; - case 'SettingsScreen.resetSettings': return 'بازنشانی تنظیمات'; - case 'SettingsScreen.cleanCache': return 'پاک کردن حافظه پنهان'; - case 'SettingsScreen.cleanCacheDone': return 'پاکسازی کامل شد'; - case 'SettingsScreen.appleTestFlight': return 'تست‌فلایت اپل'; - case 'SettingsScreen.appleAppStore': return 'اپ‌استور اپل'; - case 'SettingsScreen.hasNewVersion': return ({required Object p}) => 'به‌روزرسانی نسخه ${p} '; - case 'SettingsScreen.follow': return 'مارو دنبال کنید'; - case 'SettingsScreen.contactUs': return 'ارتباط باما'; - case 'SettingsScreen.rateInApp': return 'امتیاز به ما'; - case 'SettingsScreen.rateInAppStore': return 'به ما در اپ‌استور امتیاز بدین'; - case 'SpeedTestSettingsScreen.title': return 'URL تست سرعت'; - case 'SpeedTestSettingsScreen.error': return 'باید یک URL معتبر https باشد'; - case 'TextToQrCodeScreen.title': return 'متن به کد QR'; - case 'TextToQrCodeScreen.convert': return 'تبدیل'; - case 'UrlTestSettingsScreen.title': return 'URL بررسی تاخیر'; - case 'UrlTestSettingsScreen.error': return 'باید یک URL معتبر https باشد'; - case 'UserAgreementScreen.privacyFirst': return 'حریم‌خصوصی شما اولویت دارد'; - case 'UserAgreementScreen.agreeAndContinue': return 'پذیرفتن و ادامه'; - case 'VersionUpdateScreen.versionReady': return ({required Object p}) => 'نسخه جدید [${p}] آماده است'; - case 'VersionUpdateScreen.update': return 'راه‌اندازی مجدد برای به‌روزرسانی'; - case 'VersionUpdateScreen.cancel': return 'الان‌ نه'; - case 'CommonWidget.diableAlwayOnVPN': return 'اگر [وی‌پی‌ان همیشه روشن] روشن است لطفا [وی‌پی‌ان همیشه روشن] را خاموش کنید و مجدد برای اتصال تلاش کنید'; - case 'CommonWidget.resetPort': return 'لطفاً پورت را به پورت موجود دیگری تغییر دهید یا برنامه ای را که پورت را اشغال می کند ببندید.'; - case 'ServerManager.noServerAvaliable': return 'هیچ سروری در دسترس نیست، لطفاً مطمئن شوید که پیوند پیکربندی یا فایل پیکربندی معتبر است، اگر پیکربندی شما از GitHub آمده است، لطفاً آدرس پیوند را از دکمه [Raw] در صفحه دریافت کنید'; - case 'ServerManager.filePathCannotEmpty': return 'مسیر فایل نمی‌تواند خالی باشد'; - case 'ServerManager.fileNotExist': return ({required Object p}) => 'فایل وجود ندارد:${p}'; - case 'ServerManager.urlCannotEmpty': return 'لینک نمی‌تواند خالی باشد'; - case 'ServerManager.invalidUrl': return 'لینک پروفایل نامعتبر است'; - case 'ServerManager.parseFailed': return 'تجزیه پروفایل انجام نشد'; - case 'main.tray.menuOpen': return ' بازکردن '; - case 'main.tray.menuExit': return ' بستن '; - case 'enable': return 'فعال‌سازی'; - case 'disable': return 'غیرفعال'; - case 'prefer': return 'اولویت'; - case 'only': return 'فقط'; - case 'open': return 'باز کن'; - case 'close': return 'بسته'; - case 'quit': return 'خروج'; - case 'add': return 'افزودن'; - case 'remove': return 'حذف'; - case 'edit': return 'ویرایش کنید'; - case 'view': return 'بررسی'; - case 'more': return 'بیشتر'; - case 'addProfile': return 'افزودن پروفایل'; - case 'addSuccess': return 'با‌موفقیت اضافه شد'; - case 'addSuccessThen': return ({required Object p}) => 'پیکربندی با موفقیت ایجاد شد، لطفاً برای مشاهده به [${p}] بروید'; - case 'addFailed': return ({required Object p}) => 'افزودن ناموفق بود:${p}'; - case 'removeConfirm': return 'آیا از حذف اطمینان دارین؟'; - case 'tips': return 'اطلاعات'; - case 'copy': return 'کپی'; - case 'ok': return 'خُب'; - case 'cancel': return 'لغو'; - case 'feedback': return 'بازخورد'; - case 'faq': return 'سوالات متداول'; - case 'download': return 'دانلود'; - case 'loading': return 'درحال بارگذاری…'; - case 'updateFailed': return ({required Object p}) => 'به‌روزرسانی ناموفق بود:${p}'; - case 'days': return 'روز'; - case 'hours': return 'ساعت'; - case 'minutes': return 'دقیقه'; - case 'seconds': return 'دومین'; - case 'protocol': return 'پروتکل'; - case 'search': return 'جستجو'; - case 'custom': return 'سفارشی'; - case 'connect': return 'اتصال'; - case 'disconnect': return 'قطع‌ اتصال'; - case 'connected': return 'وصل شد'; - case 'disconnected': return 'قطع شد'; - case 'connecting': return 'درحال اتصال'; - case 'connectTimeout': return 'اتمام مهلت اتصال'; - case 'timeout': return 'تایم اوت'; - case 'language': return 'زبان'; - case 'next': return 'بعدی'; - case 'done': return 'انجام‌شد'; - case 'apply': return 'درخواست دادن'; - case 'refresh': return 'بارگذاری مجدد'; - case 'retry': return 'دوباره امتحان کنید؟'; - case 'none': return 'هیچ‌کدام'; - case 'reset': return 'ریست'; - case 'submit': return 'ارسال'; - case 'account': return 'نام‌کاربری'; - case 'password': return 'رمز‌عبور'; - case 'required': return 'الزامی'; - case 'diversion': return 'انحراف'; - case 'diversionRules': return 'قوانین انحراف'; - case 'diversionRulesEnable': return 'قوانین بارگیری [ISP] را فعال کنید'; - case 'diversionCustomGroup': return 'گروه انحراف سفارشی'; - case 'diversionCustomGroupPreset': return 'از پیش تنظیم شده [گروه انحراف سفارشی]'; - case 'diversionCustomGroupPresetTips': return 'توجه: موارد فعال به [گروه انحراف سفارشی] و [قوانین انحراف] اضافه/پوشش داده خواهند شد'; - case 'diversionCustomGroupAddTips': return 'توجه: ممکن است لازم باشد پس از افزودن مرتب‌سازی به‌صورت دستی آن را تنظیم کنید، در غیر این صورت انحراف تازه اضافه‌شده ممکن است اعمال نشود.'; - case 'urlTestCustomGroup': return 'گروه پروکسی سفارشی'; - case 'rulesetEnableTips': return 'راهنمایی: پس‌از ذخیره کردن لطفا به [قوانین انحراف] رفته و قوانین مربوط زا تنظیم کنید؛ درغیراین صورت اعمال نخواهند شد'; - case 'ispUserAgentTips': return '[ISP] انواع مختلف داده های اشتراک را بر اساس [UserAgent] در درخواست [HTTP] ارائه خواهد کرد.'; - case 'ispDiversionTips': return 'قوانین بارگذاری ارائه شده توسط [ISP]، اشتراک های نوع [V2Ray] از قوانین تخلیه پشتیبانی نمی کنند'; - case 'staticIP': return 'IP استاتیک'; - case 'other': return 'دیگر'; - case 'dns': return 'DNS'; - case 'url': return 'URL'; - case 'isp': return 'ISP'; - case 'tls': return 'TLS'; - case 'userAgent': return 'UserAgent'; - case 'urlInvalid': return 'URL نامعتبر'; - case 'outboundActionCurrentSelected': return 'فعلی انتخاب شده'; - case 'outboundActionUrltest': return 'انتخاب خودکار'; - case 'outboundActionDirect': return 'مستقیم'; - case 'outboundActionBlock': return 'مسدود'; - case 'routeFinal': return 'نهایی'; - case 'rulesetGeoSite': return 'GeoSite'; - case 'rulesetGeoIp': return 'GeoIP'; - case 'rulesetAcl': return 'ACL'; - case 'iCloud': return 'iCloud'; - case 'appleTV': return 'Apple TV'; - case 'webdav': return 'Webdav'; - case 'setting': return 'تنظیمات'; - case 'protocolSniff': return 'تشخیص پروتکل'; - case 'protocolSniffOverrideDestination': return 'نام دامنه شناسایی شده آدرس هدف اتصال را پوشش می دهد'; - case 'remark': return 'ملاحضات'; - case 'remarkCannotEmpty': return 'ملاحظات نمی‌تواند خالی باشد'; - case 'remarkTooLong': return 'ملاحظات تا ۳۲ حرف'; - case 'remarkExist': return 'ملاحظات از‌قبل وجود دارد، لطفا از نام دیگری استفاده کنید'; - case 'domainSuffix': return 'پسوند دامنه'; - case 'domain': return 'دامنه'; - case 'domainKeyword': return 'کلید‌واژه دامنه'; - case 'domainRegex': return 'عبارات باقاعده ی دامنه (Regex)'; - case 'ip': return 'IP'; - case 'port': return 'پورت'; - case 'appPackage': return 'نام بسته‌ی برنامه'; - case 'processName': return 'نام اجرایی پروسه'; - case 'processPath': return 'مسیر پروسه'; - case 'systemProxy': return 'پروکسی سیستم'; - case 'netInterfaces': return 'رابط شبکه'; - case 'netSpeed': return 'سرعت'; - case 'website': return 'وبسایت'; - case 'rule': return 'قانون'; - case 'global': return 'عمومی'; - case 'qrcode': return 'کد QR'; - case 'scanQrcode': return 'اسکن QRکد'; - case 'scanResult': return 'نتایج اسکن'; - case 'backupAndSync': return 'پشتیبان‌گیری و همگام‌سازی'; - case 'importAndExport': return 'وارد‌کردن و خروجی‌گرفتن'; - case 'import': return 'وارد‌کردن'; - case 'export': return 'خروجی‌گرفتن'; - case 'termOfUse': return 'شرایط استفاده'; - case 'privacyPolicy': return 'سیاست حریم خصوصی'; - case 'about': return 'درباره'; - case 'name': return 'نام'; - case 'version': return 'نسخه'; - case 'notice': return 'اطلاعیه'; - case 'sort': return 'مرتب‌سازی'; - case 'novice': return 'حالت مبتدی'; - case 'recommended': return 'پیشنهادی'; - case 'innerError': return ({required Object p}) => 'خطای داخلی: ${p}'; - case 'logicOperation': return 'عملیات منطقی'; - case 'share': return 'اشتراک گذاری'; - case 'candidateWord': return 'کلمات نامزد'; - case 'keywordsOrRegx': return 'کلمات کلیدی / معمولی'; - case 'importFromClipboard': return 'افزودن از کلیپ‌برد'; - case 'exportToClipboard': return 'صادرات به کلیپ بورد'; - case 'server': return 'سرور'; - case 'appleTVConnectTurnOfprivateDirect': return 'لطفاً ابتدا [اتصال مستقیم شبکه خصوصی] را فعال کنید'; - case 'targetConnectFailed': return ({required Object p}) => 'اتصال به [${p}] ناموفق بود، لطفاً مطمئن شوید که دستگاه در همان LAN است و [اتصال مستقیم شبکه خصوصی] را فعال کنید.'; - case 'appleTVSync': return 'همگام سازی پیکربندی هسته فعلی با Apple TV - Karing'; - case 'appleTVSyncDone': return 'همگام سازی کامل شد، لطفاً برای باز کردن/راه اندازی مجدد اتصال به Apple TV - Karing بروید'; - case 'appleTVRemoveCoreConfig': return 'حذف Apple TV - Karing Core Configuration'; - case 'appleTVRemoveCoreConfigDone': return 'Apple TV - نمایه اصلی کارینگ حذف شد'; - case 'appleTVUrlInvalid': return 'URL نامعتبر است، لطفاً Apple TV - Karing را باز کنید، کد QR نمایش داده شده توسط Karing را اسکن کنید'; - case 'remoteProfileEditConfirm': return 'پس از به روز رسانی تنظیمات، تغییرات گره بازیابی می شوند آیا می خواهید ادامه دهید؟'; - case 'invalidFileType': return ({required Object p}) => 'نوع فایل نامعتبر:${p}'; - case 'locales.en': return 'English'; - case 'locales.zh-CN': return '简体中文'; - case 'locales.ar': return 'عربي'; - case 'locales.ru': return 'Русский'; - case 'locales.fa': return 'فارسی'; - default: return null; - } - } -} - -extension on _StringsRu { - dynamic _flatMapFunction(String path) { - switch (path) { - case 'AboutScreen.installRefer': return 'Установленная ссылка'; - case 'AboutScreen.versionChannel': return 'Автоматически обновлять канал'; - case 'AboutScreen.disableUAReport': return 'Отключить аналитику'; - case 'AboutScreen.disableUAReportTip': return 'Отчеты о поведенческих данных помогают нам улучшить работу с продуктом; версии ниже основной версии автоматически отключают все отчеты о данных (кроме [Активации приложения]).'; - case 'AboutScreen.devOptions': return 'Параметры разработчика'; - case 'AboutScreen.enableDebugLog': return 'Включить debug-лог'; - case 'AboutScreen.viewFilsContent': return 'Посмотреть файлы'; - case 'AboutScreen.enablePprof': return 'Включить pprof'; - case 'AboutScreen.pprofPanel': return 'pprof панель'; - case 'AboutScreen.openDir': return 'Открыть каталог файлов'; - case 'AboutScreen.useOriginalSBProfile': return 'Использовать исходную конфигурацию Sing-box'; - case 'AddProfileByImportFromFileScreen.title': return 'Импорт файла конфигурации'; - case 'AddProfileByImportFromFileScreen.chooseFile': return 'Выбрать файл'; - case 'AddProfileByImportFromFileScreen.configExist': return 'Профиль уже существует. Пожалуйста, не добавляйте его повторно'; - case 'AddProfileByLinkOrContentScreen.title': return 'Добавление подписки'; - case 'AddProfileByLinkOrContentScreen.updateTimerInterval': return 'Интервал обновления'; - case 'AddProfileByLinkOrContentScreen.updateTimerIntervalTips': return 'Чтобы отключить, установите:< 5 мин'; - case 'AddProfileByLinkOrContentScreen.profileLinkContent': return 'Ссылка на подписку/содержание'; - case 'AddProfileByLinkOrContentScreen.profileLinkContentHit': return 'Ссылка на подписку/содержание [обязательно] (Поддерживаются Clash, V2ray(c пакетом поддержки), Stash, Karing, Sing-box, Shadowsocks, Sub; Ссылка на конфигурацию).'; - case 'AddProfileByLinkOrContentScreen.subscriptionCannotEmpty': return 'Ссылка на подписку не может быть пустой'; - case 'AddProfileByLinkOrContentScreen.configExist': return 'Профиль уже существует. Пожалуйста, не добавляйте его повторно'; - case 'AddProfileByLinkOrContentScreen.invalidUrl': return 'Ссылка на подписку слишком длинная'; - case 'AddProfileByLinkOrContentScreen.addFailedFormatException': return ({required Object p}) => 'Неправильный формат, исправьте его и добавьте еще раз:${p}'; - case 'AddProfileByLinkOrContentScreen.addFailedThenDownloadAndImport': return ({required Object p}) => 'Не удалось добавить: ${p}. Попробуйте изменить [UserAgent] и повторите попытку, или используйте собственный браузер устройства, чтобы открыть ссылку на конфигурацию и импортировать файл конфигурации, загруженный браузером, в это приложение.'; - case 'AddProfileByLinkOrContentScreen.addFailedHandshakeException': return ({required Object p}) => 'Не удалось добавить: ${p}, откройте агент или измените текущий узел агента и повторите попытку.'; - case 'AddProfileByScanQrcodeScanScreen.copy': return 'Скопировать ссылку'; - case 'AddProfileByScanQrcodeScanScreen.open': return 'Открыть ссылку'; - case 'AddProfileByScanQrcodeScanScreen.requestCameraPermission': return 'Пожалуйста, разрешите приложению доступ к камере'; - case 'AddProfileByScanQrcodeScanScreen.requestScreenAccess': return 'Пожалуйста, перейдите в «Настройки системы» — «Конфиденциальность и безопасность» — «Запись экрана», чтобы добавить разрешения для этого приложения'; - case 'AddProfileByScanQrcodeScanScreen.screenshot': return 'Скриншот'; - case 'AddProfileByScanQrcodeScanScreen.scanFromImage': return 'Открыть'; - case 'AddProfileByScanQrcodeScanScreen.scanNoResult': return 'Не удалось проанализировать изображение. Убедитесь, что снимок экрана представляет собой действительный QR-код.'; - case 'AddProfileByScanQrcodeScanScreen.scanEmptyResult': return 'Пустой результат сканирования.'; - case 'AddProfileByScanQrcodeScanScreen.scanException': return ({required Object p}) => 'Не удалось проанализировать изображение. Убедитесь, что снимок экрана представляет собой действительный QR-код:${p}'; - case 'BackupAndSyncLanSyncScreen.title': return 'Синхронизация по локальной сети'; - case 'BackupAndSyncLanSyncScreen.lanSyncNotQuitTips': return 'Не выходите из этого окна до завершения синхронизации.'; - case 'BackupAndSyncWebdavScreen.webdavServerUrl': return 'Адрес сервера'; - case 'BackupAndSyncWebdavScreen.webdavRequired': return 'Не может быть пустым'; - case 'BackupAndSyncWebdavScreen.webdavLoginFailed': return 'Ошибка входа:'; - case 'BackupAndSyncWebdavScreen.webdavListFailed': return 'Не удалось получить список файлов:'; - case 'DiversionGroupCustomEditScreen.invalidDomain': return ({required Object p}) => 'Неверный [Domain]:${p}'; - case 'DiversionGroupCustomEditScreen.invalidIpCidr': return ({required Object p}) => 'Неверный [IP Cidr]:${p}'; - case 'DiversionGroupCustomEditScreen.invalidPort': return ({required Object p}) => 'Неверный [Port]:${p}'; - case 'DiversionGroupCustomEditScreen.invalidRuleSet': return ({required Object p}) => 'Неверный [Rule Set]:${p}, URL-адрес должен быть действительным URL-адресом https двоичного файлом с расширением .srs/.json'; - case 'DiversionGroupCustomEditScreen.invalidRuleSetBuildIn': return ({required Object p}) => 'Неверный [RuleSet(build-in)]:${p}, формат: geosite:xxx или geoip:xxx или acl:xxx, а xxx должно быть допустимым именем правила.'; - case 'DiversionGroupCustomEditScreen.setDiversionRule': return 'Совет: после сохранения перейдите в раздел [Правила перенаправления] и установите их, иначе изменения не будут действовать.'; - case 'DiversionRuleDetectScreen.title': return 'Тест правил перенаправления'; - case 'DiversionRuleDetectScreen.detect': return 'Тест'; - case 'DiversionRuleDetectScreen.rule': return 'Правило:'; - case 'DiversionRuleDetectScreen.outbound': return 'Прокси-сервер:'; - case 'DiversionRulesScreen.diversionRulesMatchTips': return 'Совет: Правила применяются по очереди сверху вниз. Если ни одно соответствие не обнаружено, то действует правило [Final]'; - case 'DnsSettingsScreen.ispCanNotEmpty': return 'ISP не может быть пустой'; - case 'DnsSettingsScreen.urlCanNotEmpty': return 'URL не может быть пустой'; - case 'DnsSettingsScreen.error': return ({required Object p}) => 'Неподдерживаемый тип:${p}'; - case 'DnsSettingsScreen.dnsDesc': return 'Первый столбец данных — это задержка запроса при прямом соединении;\nВторой столбец, если включено [[действующий поток]Разрешать DNS через прокси-сервер]: данные — это задержка запроса, пересылаемого через текущий прокси-сервер; Если выключено [[действующий поток] Разрешать DNS через прокси-сервер]: данные - это задержка запроса при прямом соединении.'; - case 'FeedbackScreen.content': return 'Содержание'; - case 'FeedbackScreen.contentHit': return 'Не более 500 символов'; - case 'FeedbackScreen.contentCannotEmpty': return 'Содержание не может быть пустым'; - case 'FileContentViewerScreen.title': return 'Просмотр содержимого файла'; - case 'FileContentViewerScreen.chooseFile': return 'Выберите файл'; - case 'FileContentViewerScreen.clearFileContent': return 'Вы уверены, что хотите очистить содержимое файла?'; - case 'FileContentViewerScreen.clearFileContentTips': return 'Вы уверены, что хотите очистить содержимое файла профиля? Очистка файла профиля может привести к потере данных или некорректной работе приложения. Действуйте осторожно.'; - case 'HomeScreen.toSelectServer': return 'Выберите сервер'; - case 'HomeScreen.invalidServer': return 'Просрочен. Пожалуйста, выберите другой'; - case 'HomeScreen.disabledServer': return 'Был отключен. Пожалуйста, выберите другой'; - case 'HomeScreen.expiredServer': return 'Нет доступного сервера: возможно, профиль устарел или отключен'; - case 'HomeScreen.systemProxyTips': return ({required Object sp, required Object hp}) => 'socks:${sp},http(s):${hp}'; - case 'HomeScreen.trafficTotal': return 'Трафик всего'; - case 'HomeScreen.trafficProxy': return 'Трафик прокси'; - case 'HomeScreen.myLinkEmpty': return 'Пожалуйста, настройте [Быструю ссылку] перед использованием'; - case 'HomeScreen.deviceNoSpace': return 'Недостаточно места на диске'; - case 'HomeScreen.tooMuchServers': return ({required Object p, required Object p1}) => 'Слишком много прокси-серверов [${p}>${p1}], и соединение может оказаться невозможным из-за ограничений системной памяти'; - case 'LaunchFailedScreen.invalidProcess': return 'Не удалось запустить приложение [Неверное имя процесса], переустановите приложение в отдельную папку'; - case 'LaunchFailedScreen.invalidProfile': return 'Не удалось запустить приложение [Не удалось получить доступ к профилю], переустановите приложение'; - case 'LaunchFailedScreen.invalidVersion': return 'Не удалось запустить приложение [Неверная версия], переустановите приложение'; - case 'LaunchFailedScreen.systemVersionLow': return 'Не удалось запустить приложение [Слишком низкая версия системы]'; - case 'LaunchFailedScreen.startFromUNC': return 'Путь установки недействителен, переустановите его по допустимому пути'; - case 'MyProfilesEditScreen.title': return 'Редактирование профилей'; - case 'MyProfilesEditScreen.urlExist': return 'URL-адрес уже существует, используйте другой URL-адрес'; - case 'MyProfilesEditScreen.updateTimerInterval': return 'Интервал обновления'; - case 'MyProfilesEditScreen.updateTimerIntervalTips': return 'Чтобы отключить, установите <5 мин'; - case 'MyProfilesEditScreen.reloadAfterProfileUpdate': return 'Перезагрузить после обновления профиля'; - case 'MyProfilesEditScreen.testLatencyAfterProfileUpdate': return 'Начать тестирование задержек после обновления профиля'; - case 'MyProfilesEditScreen.testLatencyAfterProfileUpdateTips': return 'VPN необходимо подключить, и включить [Перезагрузить после обновления профиля]'; - case 'MyProfilesEditScreen.testLatencyAutoRemove': return 'Автоматически удалять серверы, не прошедшие тесты на задержку'; - case 'MyProfilesEditScreen.testLatencyAutoRemoveTips': return 'Попробуйте до 3 раз'; - case 'MyProfilesMergeScreen.profilesMerge': return 'Объединение профилей'; - case 'MyProfilesMergeScreen.profilesMergeTarget': return 'Целевой профиль'; - case 'MyProfilesMergeScreen.profilesMergeSource': return 'Профиль - источник'; - case 'MyProfilesMergeScreen.profilesMergeTips': return 'Совет: Настройки перенаправления для профиля - источника будут удалены.'; - case 'MyProfilesScreen.title': return 'Профили'; - case 'MyProfilesScreen.atLeastOneEnable': return 'Невозможно отключить, оставьте включенным хотя бы один профиль'; - case 'NetCheckScreen.title': return 'Диагностика сети'; - case 'NetCheckScreen.warn': return 'Примечание. Из-за влияния сетевой среды и правил перенаправления результаты теста не полностью эквивалентны фактическим результатам.'; - case 'NetCheckScreen.check': return 'Тест'; - case 'NetCheckScreen.invalidDomain': return 'Неверное имя домена'; - case 'NetCheckScreen.connectivity': return 'Подключение к сети'; - case 'NetCheckScreen.connectivityTestIpv4AllFailed': return ({required Object p}) => 'Ipv4 Тест подключения[${p}] неудачен'; - case 'NetCheckScreen.connectivityTestIpv4Ok': return 'Ipv4 Соединение выполнено успешно'; - case 'NetCheckScreen.connectivityTestIpv6AllFailed': return ({required Object p}) => 'Ipv6 Тест подключения[${p}] неудачен. Возможно, ваша сеть не поддерживает ipv6.'; - case 'NetCheckScreen.connectivityTestIpv6Ok': return 'Ipv6 Соединение выполнено успешно'; - case 'NetCheckScreen.connectivityTestOk': return 'Сеть подключена к Интернету'; - case 'NetCheckScreen.connectivityTestFailed': return 'Ваша сеть не подключена к Интернету'; - case 'NetCheckScreen.remoteRulesetsDownloadOk': return 'Все успешно скачано'; - case 'NetCheckScreen.remoteRulesetsDownloadNotOk': return 'Загрузка или сбой'; - case 'NetCheckScreen.outbound': return 'Прокси-сервер'; - case 'NetCheckScreen.outboundOk': return ({required Object p}) => '[${p}]Соединение установлено успешно'; - case 'NetCheckScreen.outboundFailed': return ({required Object p1, required Object p2}) => '[${p1}]Соединение не удалось\nошибка:[${p2}]'; - case 'NetCheckScreen.dnsServer': return 'DNS сервер'; - case 'NetCheckScreen.dnsOk': return ({required Object p1, required Object p2, required Object p3, required Object p4}) => '[${p1}]DNS Разобрано успешно\nDNS правило:[${p2}]\nЗадержка:[${p3} ms]\nадрес:[${p4}]'; - case 'NetCheckScreen.dnsFailed': return ({required Object p1, required Object p2, required Object p3}) => '[${p1}]DNS Не удалось выполнить синтаксический анализ\n правило:[${p2}]\nошибка:[${p3}]'; - case 'NetCheckScreen.host': return 'HTTP соединение'; - case 'NetCheckScreen.hostConnection': return ({required Object p1, required Object p2, required Object p3}) => '[${p1}]\nПравила перенаправления:[${p2}]\nПрокси-сервер:[${p3}]'; - case 'NetCheckScreen.hostConnectionOk': return 'Соединение установлено успешно'; - case 'NetCheckScreen.hostConnectionFailed': return ({required Object p}) => 'Соединение не удалось:[${p}]'; - case 'NetConnectionsFilterScreen.title': return 'Фильтр соединений'; - case 'NetConnectionsFilterScreen.hostIp': return 'Domain/IP'; - case 'NetConnectionsFilterScreen.app': return 'Приложение'; - case 'NetConnectionsFilterScreen.rule': return 'Правило'; - case 'NetConnectionsFilterScreen.chain': return 'Исходящий'; - case 'NetConnectionsScreen.title': return 'Соединения'; - case 'NetConnectionsScreen.copyAsCSV': return 'Скопировано в CSV формате'; - case 'NetConnectionsScreen.selectType': return 'Выберите тип перенаправления'; - case 'PerAppAndroidScreen.title': return 'Проксируемые приложения'; - case 'PerAppAndroidScreen.whiteListMode': return 'Режим белого списка'; - case 'PerAppAndroidScreen.whiteListModeTip': return 'Если включено: перенаправляются через прокси-сервер только те приложения, которые были отмечены. Если выключено: перенаправляются через прокси-сервер только те приложения, которые не были отмечены.'; - case 'PerAppAndroidScreen.hideSystemApp': return 'Скрыть системные приложения'; - case 'PerAppAndroidScreen.hideAppIcon': return 'Скрыть значок приложения'; - case 'PerAppAndroidScreen.enableAppQueryPermission': return 'Включать разрешения [на запросы списка приложений]'; - case 'QrcodeScreen.tooLong': return 'Слишком большой текст для отображения'; - case 'QrcodeScreen.copy': return 'Скопировать ссылку'; - case 'QrcodeScreen.open': return 'Открыть ссылку'; - case 'QrcodeScreen.share': return 'Поделиться ссылкой'; - case 'QrcodeScreen.shareImage': return 'Поделиться QR-кодом'; - case 'RegionSettingsScreen.title': return 'Страна или регион'; - case 'RegionSettingsScreen.Regions': return 'Совет: Пожалуйста, правильно укажите текущую страну или регион. В противном случае это может вызвать проблемы с перенаправлением в сети'; - case 'ServerSelectScreen.title': return 'Выбор сервера'; - case 'ServerSelectScreen.autoSelectServer': return 'Автовыбор сервера с наименьшей задержкой'; - case 'ServerSelectScreen.recentUse': return 'Недавно использованные'; - case 'ServerSelectScreen.myFav': return 'Мои избранные'; - case 'ServerSelectScreen.selectLocal': return ({required Object p}) => 'Выбранный сервер является локальным, и может работать неправильно:${p}'; - case 'ServerSelectScreen.selectRequireEnableIPv6': return 'Выбранный сервер имеет адрес IPv6 и требует [Включить IPv6]'; - case 'ServerSelectScreen.selectDisabled': return 'Сервер отключен'; - case 'ServerSelectScreen.error404': return 'При измерении задержки произошла ошибка. Проверьте, существует ли профиль с таким содержимым.'; - case 'SettingsScreen.ispFaq': return ({required Object p}) => 'FAQ[${p}]'; - case 'SettingsScreen.cleanISP': return ({required Object p}) => 'Очистить ISP[${p}]'; - case 'SettingsScreen.openISP': return 'Открыть ссылку на провайдера'; - case 'SettingsScreen.cleanISPNoParam': return 'Очистить информацию об интернет-провайдере'; - case 'SettingsScreen.getTranffic': return 'Получить трафик'; - case 'SettingsScreen.tutorial': return 'Руководство'; - case 'SettingsScreen.commonlyUsedRulesets': return 'Часто используемые наборы правил'; - case 'SettingsScreen.howToRemoveAds': return 'Как удалить рекламу'; - case 'SettingsScreen.htmlBoard': return 'Веб-панель'; - case 'SettingsScreen.dnsLeakDetection': return 'Обнаружение утечки DNS'; - case 'SettingsScreen.speedTest': return 'Тест скорости'; - case 'SettingsScreen.downloadProfilePreferProxy': return 'Настройка приоритетного выбора прокси-сервера'; - case 'SettingsScreen.downloadProfilePreferProxyTips': return 'Если подключение установлено, профиль вначале будет загружен через подключенный прокси-сервер'; - case 'SettingsScreen.rulesetDirectDownlad': return 'Rule Set Прямой доступ'; - case 'SettingsScreen.hideUnusedDiversionGroup': return 'Скрыть неактивные правила перенаправления'; - case 'SettingsScreen.disableISPDiversionGroup': return 'Отключить правила перенаправления ISP'; - case 'SettingsScreen.portSetting': return 'Порт'; - case 'SettingsScreen.portSettingRule': return 'Основано на правилах'; - case 'SettingsScreen.portSettingDirectAll': return 'Полное прямое соединение'; - case 'SettingsScreen.portSettingProxyAll': return 'Прокси для всего'; - case 'SettingsScreen.portSettingControl': return 'Управление и синхронизация'; - case 'SettingsScreen.portSettingCluster': return 'Кластерный сервис'; - case 'SettingsScreen.modifyPort': return 'Изменить порт'; - case 'SettingsScreen.ipStrategyTips': return 'Перед включением убедитесь, что ваша сеть поддерживает IPv6, в противном случае нормальный доступ к части трафика будет невозможен'; - case 'SettingsScreen.tunAppendHttpProxy': return 'Подключите HTTP-прокси к VPN'; - case 'SettingsScreen.tunAppendHttpProxyTips': return 'Некоторые приложения будут обходить устройство виртуальной сетевой карты и напрямую подключаться к HTTP-прокси.'; - case 'SettingsScreen.tlsInsecureEnable': return 'Пропустить проверку сертификата'; - case 'SettingsScreen.tlsFragmentEnable': return 'Включить сегментацию TLS'; - case 'SettingsScreen.tlsFragmentSize': return 'Размер сегмента TLS'; - case 'SettingsScreen.tlsFragmentSleep': return 'Сегментированный сон TLS'; - case 'SettingsScreen.tlsMixedCaseSNIEnable': return 'Включить гибридный SNI TLS'; - case 'SettingsScreen.tlsPaddingEnable': return 'Включить заполнение TLS'; - case 'SettingsScreen.tlsPaddingSize': return 'Размер заполнения TLS'; - case 'SettingsScreen.dnsEnableRule': return 'Включить правила DNS'; - case 'SettingsScreen.dnsEnableFakeIp': return 'Включить FakeIP'; - case 'SettingsScreen.dnsEnableClientSubnet': return 'Включить ECS'; - case 'SettingsScreen.dnsEnableProxyResolveByProxy': return '[действующий поток] Разрешать DNS через прокси-сервер'; - case 'SettingsScreen.dnsEnableFinalResolveByProxy': return '[final] Разрешать DNS через прокси-сервер'; - case 'SettingsScreen.dnsTestDomain': return 'Тестовое доменное имя'; - case 'SettingsScreen.dnsTestDomainInvalid': return 'Неверное доменное имя'; - case 'SettingsScreen.dnsTypeOutbound': return 'Прокси-сервер'; - case 'SettingsScreen.dnsTypeDirect': return 'Прямой поток'; - case 'SettingsScreen.dnsTypeProxy': return 'Действующий поток'; - case 'SettingsScreen.dnsTypeResolver': return 'DNS-сервер'; - case 'SettingsScreen.dnsEnableRuleTips': return 'После включения, доменное имя выберет соответствующий DNS-сервер для разрешения в соответствии с правилами перенаправления.'; - case 'SettingsScreen.dnsEnableFakeIpTips': return 'После включения FakeIP, если VPN-соединение отключено, возможно, потребуется перезапустить приложение, эту функцию необходимо включить [Режим TUN];'; - case 'SettingsScreen.dnsTypeOutboundTips': return 'Для разрешения доменных имен прокси-сервера рекомендуется использовать безопасный DNS'; - case 'SettingsScreen.dnsTypeDirectTips': return 'Разрешение доменных имен для прямого потока'; - case 'SettingsScreen.dnsTypeProxyTips': return 'Разрешение доменных имен для действующего потока'; - case 'SettingsScreen.dnsTypeResolverTips': return 'Разрешение доменных имен для DNS-серверов'; - case 'SettingsScreen.dnsTypeFinalTips': return 'Разрешение доменных имен для потока Final'; - case 'SettingsScreen.dnsAutoSetServer': return 'Автоматически настроить сервер'; - case 'SettingsScreen.dnsResetServer': return 'Сбросить сервер'; - case 'SettingsScreen.inboundDomainResolve': return 'Разрешение входящих доменных имен'; - case 'SettingsScreen.privateDirect': return 'Прямое подключение к частной сети'; - case 'SettingsScreen.inboundDomainResolveTips': return ({required Object p}) => 'Некоторые доменные имена без настроенных правил переадресации необходимо разрешить, прежде чем они смогут соответствовать правилам переадресации на основе IP; эта функция влияет на входящие запросы к порту прокси [${p}]'; - case 'SettingsScreen.useRomoteRes': return 'Использовать удаленные ресурсы'; - case 'SettingsScreen.autoSelect': return 'Автовыбор'; - case 'SettingsScreen.autoSelectServerIgnorePerProxyServer': return 'Игнорировать прокси-сервер [передний прокси]'; - case 'SettingsScreen.autoSelectServerInterval': return 'Интервал проверок задержки'; - case 'SettingsScreen.autoSelectServerReTestIfNetworkUpdate': return 'Перетестировать после смены сети'; - case 'SettingsScreen.autoSelectServerIntervalTips': return 'Чем короче временной интервал, тем чаще обновляются данные о задержке сервера. Но это потребует больше ресурсов и энергии'; - case 'SettingsScreen.autoSelectServerFavFirst': return 'Приоритетно [Мои избранные]'; - case 'SettingsScreen.autoSelectServerUpdateCurrentServerAfterManualUrltest': return 'Обновить текущий сервер после измерения задержки вручную'; - case 'SettingsScreen.autoSelectServerFavFirstTips': return 'Если список [Мои избранные] не пуст, то будут использоваться серверы из [Мои избранные]'; - case 'SettingsScreen.autoSelectServerFilter': return 'Отфильтровать сервера'; - case 'SettingsScreen.autoSelectServerFilterTips': return ({required Object p}) => 'Ошибки превышения задержки сервера будут отфильтрованы; если после фильтрации ни один сервер не будет доступен, вместо него будут использоваться первые [${p}] серверы'; - case 'SettingsScreen.autoSelectServerLimitedNum': return 'Максимальное количество серверов'; - case 'SettingsScreen.autoSelectServerLimitedNumTips': return 'Серверы, превышающие это число, будут отфильтрованы.'; - case 'SettingsScreen.numInvalid': return 'Неправильный номер'; - case 'SettingsScreen.hideInvalidServer': return 'Скрыть нерабочие серверы'; - case 'SettingsScreen.sortServer': return 'Сортировка серверов'; - case 'SettingsScreen.sortServerTips': return 'Сортировать по задержке от низкой к высокой'; - case 'SettingsScreen.selectServerHideRecommand': return 'Скрыть [Рекомендуемые]'; - case 'SettingsScreen.selectServerHideRecent': return 'Скрыть [Недавно использованные]'; - case 'SettingsScreen.selectServerHideFav': return 'Скрыть [Мои избранные]'; - case 'SettingsScreen.homeScreen': return 'Домашний экран'; - case 'SettingsScreen.theme': return 'Тема'; - case 'SettingsScreen.myLink': return 'Быстрая ссылка'; - case 'SettingsScreen.myLinkInvalid': return 'Неверный URL'; - case 'SettingsScreen.autoConnectAfterLaunch': return 'Автоматическое подключение после запуска'; - case 'SettingsScreen.hideAfterLaunch': return 'Скрыть окно после запуска'; - case 'SettingsScreen.autoSetSystemProxy': return 'Установить прокси после подключения'; - case 'SettingsScreen.disconnectWhenQuit': return 'Отключаться при выходе из приложения'; - case 'SettingsScreen.allowBypass': return 'Разрешить приложениям обходить VPN'; - case 'SettingsScreen.lanSyncTo': return 'Синхронизировать на другие устройства'; - case 'SettingsScreen.lanSyncFrom': return 'Синхронизация с других устройств'; - case 'SettingsScreen.lanSyncScanQRcode': return 'Сканируйте QR-код для синхронизации'; - case 'SettingsScreen.syncToConfirm': return 'Подтвердить синхронизацию с собеседником?'; - case 'SettingsScreen.syncDone': return 'Синхронизация завершена'; - case 'SettingsScreen.importSuccess': return 'Импорт выполнен успешно'; - case 'SettingsScreen.rewriteConfirm': return 'Этот файл перезапишет существующую локальную конфигурацию. Продолжить?'; - case 'SettingsScreen.networkShare': return 'Общий доступ к сети'; - case 'SettingsScreen.frontProxy': return 'Фронт-прокси'; - case 'SettingsScreen.frontProxyTips': return 'Запрос -> фронт-прокси сервер -> прокси-сервер -> целевой сервер'; - case 'SettingsScreen.allowOtherHostsConnect': return 'Разрешить подключаться другим'; - case 'SettingsScreen.allowOtherHostsConnectTips': return ({required Object sp, required Object hp}) => 'socks:${sp},http(s):${hp}'; - case 'SettingsScreen.tunAutoRoute': return 'Auto Route'; - case 'SettingsScreen.tunStrictRoute': return 'Strict Route'; - case 'SettingsScreen.tunStrictRouteTips': return 'Если после включения общего доступа другие люди не смогут получить доступ к этому устройству, попробуйте отключить этот переключатель.'; - case 'SettingsScreen.enableCluster': return 'Включить кластер прокси Socks/Http'; - case 'SettingsScreen.clusterAllowOtherHostsConnect': return 'Разрешить подключаться другим'; - case 'SettingsScreen.clusterAllowOtherHostsConnectTips': return ({required Object hp}) => 'http://127.0.0.1:${hp}/get_proxies'; - case 'SettingsScreen.clusterAuth': return 'Аутентификация прокси-кластера'; - case 'SettingsScreen.clusterConfirm': return 'Пожалуйста, подтвердите, что задержка серверов проверена. Прокси-сервисы не будут созданы, если они не проверены или проверены неверно'; - case 'SettingsScreen.tunMode': return 'Режим TUN'; - case 'SettingsScreen.tunModeTips': return 'В режиме TUN весь трафик системы будет перенаправлен через соединение [В этом режиме вы можете оставить системный прокси отключенным]'; - case 'SettingsScreen.tunModeRunAsAdmin': return 'Для режима TUN требуются права администратора. Перезапустите приложение от имени администратора'; - case 'SettingsScreen.tunStack': return 'Stack'; - case 'SettingsScreen.launchAtStartup': return 'Запуск при включении'; - case 'SettingsScreen.quitWhenSwitchSystemUser': return 'Переключить пользователя для выхода'; - case 'SettingsScreen.handleScheme': return 'Использовать схему системы с предварительным звонком'; - case 'SettingsScreen.portableMode': return 'Портативный режим'; - case 'SettingsScreen.portableModeDisableTips': return 'Если вам нужно выйти из портативного режима, выйдите из [karing] и вручную удалите папку [profiles] в том же каталоге, что и [karing.exe]'; - case 'SettingsScreen.handleKaringScheme': return 'Кнопка karing:// Позвонить'; - case 'SettingsScreen.handleClashScheme': return 'Кнопка clash:// Позвонить'; - case 'SettingsScreen.handleSingboxScheme': return 'Кнопка sing-box:// Позвонить'; - case 'SettingsScreen.removeSystemVPNConfig': return 'Удалить профиль VPN'; - case 'SettingsScreen.timeConnectOrDisconnect': return 'Запланированное подключение/отключение'; - case 'SettingsScreen.timeConnectOrDisconnectTips': return 'Чтобы это заработало, необходимо подключить VPN; после его подключения [автоматическое засыпание] будет отключено'; - case 'SettingsScreen.timeConnectAndDisconnectInterval': return ({required Object p}) => 'Интервал подключения/отключения не может быть меньше ${p} минут.'; - case 'SettingsScreen.disableFontScaler': return 'Отключить масштабирование шрифта'; - case 'SettingsScreen.autoOrientation': return 'Следите за поворотом экрана'; - case 'SettingsScreen.restartTakesEffect': return 'Требуется перезапуск'; - case 'SettingsScreen.resetSettings': return 'Сброс настроек'; - case 'SettingsScreen.cleanCache': return 'Очистка кэша'; - case 'SettingsScreen.cleanCacheDone': return 'Очистка завершена'; - case 'SettingsScreen.appleTestFlight': return 'Apple TestFlight'; - case 'SettingsScreen.appleAppStore': return 'Apple AppStore'; - case 'SettingsScreen.hasNewVersion': return ({required Object p}) => 'Обновить версию ${p}'; - case 'SettingsScreen.follow': return 'Подписаться на нас'; - case 'SettingsScreen.contactUs': return 'Связаться с нами'; - case 'SettingsScreen.rateInApp': return 'Оценить нас'; - case 'SettingsScreen.rateInAppStore': return 'Оценить нас в App Store'; - case 'SpeedTestSettingsScreen.title': return 'URL-адрес теста скорости'; - case 'SpeedTestSettingsScreen.error': return 'https URL должен быть действительным'; - case 'TextToQrCodeScreen.title': return 'Преобразование текста в QR-код'; - case 'TextToQrCodeScreen.convert': return 'Конвертировать'; - case 'UrlTestSettingsScreen.title': return 'URL-адрес измерения задержки'; - case 'UrlTestSettingsScreen.error': return 'https URL должен быть действительным'; - case 'UserAgreementScreen.privacyFirst': return 'Ваша конфиденциальность превыше всего'; - case 'UserAgreementScreen.agreeAndContinue': return 'Принять и продолжить'; - case 'VersionUpdateScreen.versionReady': return ({required Object p}) => 'Новая версия [${p}] доступна'; - case 'VersionUpdateScreen.update': return 'Перезапустить'; - case 'VersionUpdateScreen.cancel': return 'Не сейчас'; - case 'CommonWidget.diableAlwayOnVPN': return 'Если параметр [VPN всегда включен] включен, отключите его и попробуйте подключиться еще раз'; - case 'CommonWidget.resetPort': return 'Пожалуйста, измените порт на другой доступный порт или закройте приложение, занимающее порт.'; - case 'ServerManager.noServerAvaliable': return 'Нет доступных серверов, убедитесь что подписка или файл профиля корректен. Если ваша конфигурация взята из GitHub, получите адрес ссылки, нажав кнопку [Raw] на странице.'; - case 'ServerManager.filePathCannotEmpty': return 'Путь к файлу не может быть пустым'; - case 'ServerManager.fileNotExist': return ({required Object p}) => 'Файла не существует:${p}'; - case 'ServerManager.urlCannotEmpty': return 'Ссылка не может быть пустой'; - case 'ServerManager.invalidUrl': return 'Некорректная ссылка на подписку'; - case 'ServerManager.parseFailed': return 'Получение подписки не удалось'; - case 'main.tray.menuOpen': return ' Открыть '; - case 'main.tray.menuExit': return ' Выйти '; - case 'enable': return 'Включить'; - case 'disable': return 'Запретить'; - case 'prefer': return 'Приоритет'; - case 'only': return 'Только'; - case 'open': return 'Открыть'; - case 'close': return 'Закрыть'; - case 'quit': return 'Выйти'; - case 'add': return 'Добавить'; - case 'remove': return 'Удалить'; - case 'edit': return 'Редактировать'; - case 'view': return 'Более'; - case 'more': return 'More'; - case 'addProfile': return 'Добавить профиль'; - case 'addSuccess': return 'Добавлено успешно'; - case 'addSuccessThen': return ({required Object p}) => 'Конфигурация сгенерирована успешно. Для просмотра перейдите в [${p}]'; - case 'addFailed': return ({required Object p}) => 'Ошибка при добавлении:${p}'; - case 'removeConfirm': return 'Подтверждаете удаление?'; - case 'tips': return 'Инфо'; - case 'copy': return 'Скопировать'; - case 'ok': return 'Ок'; - case 'cancel': return 'Закрыть'; - case 'feedback': return 'Обратная связь'; - case 'faq': return 'Часто задаваемые вопросы (FAQ)'; - case 'download': return 'Скачать'; - case 'loading': return 'Загрузка...'; - case 'updateFailed': return ({required Object p}) => 'Не удалось обновить:${p}'; - case 'days': return 'дни'; - case 'hours': return 'часы'; - case 'minutes': return 'минуты'; - case 'seconds': return 'Второй'; - case 'protocol': return 'Протокол'; - case 'search': return 'Поиск'; - case 'custom': return 'Настроить самостоятельно'; - case 'connect': return 'Соединить'; - case 'disconnect': return 'Отключить'; - case 'connected': return 'Подключено'; - case 'disconnected': return 'Отключено'; - case 'connecting': return 'Подключение'; - case 'connectTimeout': return 'Таймаут при соединении'; - case 'timeout': return 'тайм-аут'; - case 'language': return 'Язык'; - case 'next': return 'Дальше'; - case 'done': return 'Готово'; - case 'apply': return 'Применить'; - case 'refresh': return 'Обновить'; - case 'retry': return 'Хотите попробовать еще раз?'; - case 'none': return 'Ничего не делать'; - case 'reset': return 'Перезагрузить'; - case 'submit': return 'Отправить'; - case 'account': return 'Аккаунт'; - case 'password': return 'Пароль'; - case 'required': return 'Необходимо'; - case 'diversion': return 'Правила'; - case 'diversionRules': return 'Правила перенаправления'; - case 'diversionRulesEnable': return 'Включить правила разгрузки [ISP]'; - case 'diversionCustomGroup': return 'Личные правила'; - case 'diversionCustomGroupPreset': return 'Шаблоны личных правил'; - case 'diversionCustomGroupPresetTips': return 'Примечание. Включенные элементы будут добавлены или включены в [Личные правила] и [Правила перенаправления].'; - case 'diversionCustomGroupAddTips': return 'Примечание. Возможно, вам придется вручную настроить сортировку после ее добавления, в противном случае добавленное перенаправление может не вступить в силу.'; - case 'urlTestCustomGroup': return 'Личная группа прокси-серверов'; - case 'rulesetEnableTips': return 'Совет: После включения опции перейдите в [Правила перенаправления] и установите их, иначе опция не будет действовать'; - case 'ispUserAgentTips': return '[ISP] будет доставлять различные типы данных о подписке на основе [UserAgent] в запросе [HTTP].'; - case 'ispDiversionTips': return 'Правила разгрузки, предоставляемые подписками типа [ISP] [V2Ray], не поддерживают правила разгрузки;'; - case 'staticIP': return 'Статический IP'; - case 'other': return 'Другой'; - case 'dns': return 'DNS'; - case 'url': return 'URL'; - case 'isp': return 'ISP'; - case 'tls': return 'TLS'; - case 'userAgent': return 'UserAgent'; - case 'urlInvalid': return 'Неверный URL'; - case 'outboundActionCurrentSelected': return 'Текущий сервер'; - case 'outboundActionUrltest': return 'Автовыбор сервера'; - case 'outboundActionDirect': return 'Напрямую'; - case 'outboundActionBlock': return 'Блокировать'; - case 'routeFinal': return 'Final'; - case 'rulesetGeoSite': return 'GeoSite'; - case 'rulesetGeoIp': return 'GeoIP'; - case 'rulesetAcl': return 'ACL'; - case 'iCloud': return 'iCloud'; - case 'appleTV': return 'Apple TV'; - case 'webdav': return 'Webdav'; - case 'setting': return 'Настройки'; - case 'protocolSniff': return 'Обнаружение протокола'; - case 'protocolSniffOverrideDestination': return 'Обнаруженное доменное имя охватывает целевой адрес подключения.'; - case 'remark': return 'Примечание'; - case 'remarkCannotEmpty': return 'Примечание не может быть пустым'; - case 'remarkTooLong': return 'Примечания до 32 символов'; - case 'remarkExist': return 'Примечание уже существует, используйте другое имя'; - case 'domainSuffix': return 'Суффикс доменного имени'; - case 'domain': return 'Имя домена'; - case 'domainKeyword': return 'Ключевые слова в имени домена'; - case 'domainRegex': return 'Регулярные выражения для имен доменов'; - case 'ip': return 'IP'; - case 'port': return 'Порт'; - case 'appPackage': return 'Имя пакета приложения'; - case 'processName': return 'Имя процесса'; - case 'processPath': return 'Путь к процессу'; - case 'systemProxy': return 'Системный прокси'; - case 'netInterfaces': return 'Сетевой интерфейс'; - case 'netSpeed': return 'Скорость'; - case 'website': return 'Веб-сайт'; - case 'rule': return 'Правила'; - case 'global': return 'Глобально'; - case 'qrcode': return 'QR-код'; - case 'scanQrcode': return 'Сканировать QR-код'; - case 'scanResult': return 'Результат сканирования'; - case 'backupAndSync': return 'Резервное копирование и синхронизация'; - case 'importAndExport': return 'Импорт и экспорт'; - case 'import': return 'Импорт'; - case 'export': return 'Экспорт'; - case 'termOfUse': return 'Условия использования'; - case 'privacyPolicy': return 'Политика конфиденциальности'; - case 'about': return 'О Karing'; - case 'name': return 'Название'; - case 'version': return 'Версия'; - case 'notice': return 'Уведомления'; - case 'sort': return 'Отсортировать'; - case 'novice': return 'Режим новичка'; - case 'recommended': return 'Рекомендуемые'; - case 'innerError': return ({required Object p}) => 'внутренняя ошибка:${p}'; - case 'logicOperation': return 'логическая операция'; - case 'share': return 'Поделиться'; - case 'candidateWord': return 'Ключевые слова'; - case 'keywordsOrRegx': return 'Ключевые слова/регулярные выражения'; - case 'importFromClipboard': return 'Импорт из буфера обмена'; - case 'exportToClipboard': return 'Экспорт в буфер обмена'; - case 'server': return 'сервер'; - case 'appleTVConnectTurnOfprivateDirect': return 'Пожалуйста, сначала включите [Прямое подключение к частной сети]'; - case 'targetConnectFailed': return ({required Object p}) => 'Не удалось подключиться к [${p}]. Убедитесь, что устройство находится в той же локальной сети, и включите [Прямое подключение к частной сети].'; - case 'appleTVSync': return 'Синхронизация текущей базовой конфигурации с Apple TV - Karing'; - case 'appleTVSyncDone': return 'Синхронизация завершена, перейдите в Apple TV — Karing, чтобы открыть/перезапустить соединение.'; - case 'appleTVRemoveCoreConfig': return 'Удаление Apple TV — базовая конфигурация Karing'; - case 'appleTVRemoveCoreConfigDone': return 'Apple TV — основной профиль Karing удален; VPN-сервис отключен;'; - case 'appleTVUrlInvalid': return 'Неверный URL-адрес. Откройте Apple TV — Karing, отсканируйте QR-код, отображаемый Karing.'; - case 'remoteProfileEditConfirm': return 'После обновления конфигурации изменения узла будут восстановлены. Продолжить?'; - case 'invalidFileType': return ({required Object p}) => 'Неверный тип файла:${p}'; - case 'locales.en': return 'English'; - case 'locales.zh-CN': return '简体中文'; - case 'locales.ar': return 'عربي'; - case 'locales.ru': return 'Русский'; - case 'locales.fa': return 'فارسی'; - default: return null; - } - } -} - -extension on _StringsZhCn { - dynamic _flatMapFunction(String path) { - switch (path) { - case 'AboutScreen.installRefer': return '安装参考'; - case 'AboutScreen.versionChannel': return '自动更新通道'; - case 'AboutScreen.disableUAReport': return '关闭行为数据上报'; - case 'AboutScreen.disableUAReportTip': return '行为数据上报有助于我们改进产品体验;低于主版本的版本将自动关闭的所有数据上报([应用激活]除外)'; - case 'AboutScreen.devOptions': return '开发者选项'; - case 'AboutScreen.enableDebugLog': return '开启调试日志'; - case 'AboutScreen.viewFilsContent': return '查看文件'; - case 'AboutScreen.enablePprof': return '启用pprof'; - case 'AboutScreen.pprofPanel': return 'pprof面板'; - case 'AboutScreen.openDir': return '打开文件目录'; - case 'AboutScreen.useOriginalSBProfile': return '使用原始sing-box配置'; - case 'AddProfileByImportFromFileScreen.title': return '导入配置文件'; - case 'AddProfileByImportFromFileScreen.chooseFile': return '选择文件'; - case 'AddProfileByImportFromFileScreen.configExist': return '配置已存在,请勿重复添加'; - case 'AddProfileByLinkOrContentScreen.title': return '添加配置链接'; - case 'AddProfileByLinkOrContentScreen.updateTimerInterval': return '更新时间间隔'; - case 'AddProfileByLinkOrContentScreen.updateTimerIntervalTips': return '禁用请设置为:<5m'; - case 'AddProfileByLinkOrContentScreen.profileLinkContent': return '配置链接/内容'; - case 'AddProfileByLinkOrContentScreen.profileLinkContentHit': return '配置链接/内容[必填] (支持Clash,V2ray(支持批量),Stash,Karing,Sing-box,Shadowsocks,Sub,Github配置链接)'; - case 'AddProfileByLinkOrContentScreen.subscriptionCannotEmpty': return '配置链接不能为空'; - case 'AddProfileByLinkOrContentScreen.configExist': return '配置已存在,请勿重复添加'; - case 'AddProfileByLinkOrContentScreen.invalidUrl': return '配置链接长度过长'; - case 'AddProfileByLinkOrContentScreen.addFailedFormatException': return ({required Object p}) => '格式错误,请订正后重新添加:${p}'; - case 'AddProfileByLinkOrContentScreen.addFailedThenDownloadAndImport': return ({required Object p}) => '添加失败:${p}, 请尝试修改[UserAgent]后重试,或者用设备自带的浏览器打开配置链接,并将浏览器下载的配置文件导入到本应用'; - case 'AddProfileByLinkOrContentScreen.addFailedHandshakeException': return ({required Object p}) => '添加失败:${p}, 请打开代理或者修改当前代理节点后重试'; - case 'AddProfileByScanQrcodeScanScreen.copy': return '拷贝链接'; - case 'AddProfileByScanQrcodeScanScreen.open': return '打开链接'; - case 'AddProfileByScanQrcodeScanScreen.requestCameraPermission': return '请开启摄像头权限'; - case 'AddProfileByScanQrcodeScanScreen.requestScreenAccess': return '请到系统设置-隐私与安全-屏幕录制 为本应用添加权限'; - case 'AddProfileByScanQrcodeScanScreen.screenshot': return '截图'; - case 'AddProfileByScanQrcodeScanScreen.scanFromImage': return '打开二维码图片'; - case 'AddProfileByScanQrcodeScanScreen.scanNoResult': return '解析图片失败,请确保截图为有效的二维码'; - case 'AddProfileByScanQrcodeScanScreen.scanEmptyResult': return '扫描结果为空'; - case 'AddProfileByScanQrcodeScanScreen.scanException': return ({required Object p}) => '解析图片异常,请确保截图为有效的二维码:${p}'; - case 'BackupAndSyncLanSyncScreen.title': return '局域网同步'; - case 'BackupAndSyncLanSyncScreen.lanSyncNotQuitTips': return '同步完成前请勿退出此界面'; - case 'BackupAndSyncWebdavScreen.webdavServerUrl': return '服务器地址'; - case 'BackupAndSyncWebdavScreen.webdavRequired': return '不能为空'; - case 'BackupAndSyncWebdavScreen.webdavLoginFailed': return '登录失败:'; - case 'BackupAndSyncWebdavScreen.webdavListFailed': return '获取文件列表失败:'; - case 'DiversionGroupCustomEditScreen.invalidDomain': return ({required Object p}) => '无效的 [Domain]:${p}'; - case 'DiversionGroupCustomEditScreen.invalidIpCidr': return ({required Object p}) => '无效的 [IP Cidr]:${p}'; - case 'DiversionGroupCustomEditScreen.invalidPort': return ({required Object p}) => '无效的 [Port]:${p}'; - case 'DiversionGroupCustomEditScreen.invalidRuleSet': return ({required Object p}) => '无效的 [Rule Set]:${p}, URL必须是有效的https URL,并且文件扩展名为.srs/.json的binary文件'; - case 'DiversionGroupCustomEditScreen.invalidRuleSetBuildIn': return ({required Object p}) => '无效的 [Rule Set(build-in)]:${p}, 格式为geosite:xxx 或 geoip:xxx 或 acl:xxx,并且xxx应为有效的规则名'; - case 'DiversionGroupCustomEditScreen.setDiversionRule': return '提示:保存后,请到[分流规则]设置相关规则,否则不会生效'; - case 'DiversionRuleDetectScreen.title': return '分流规则探测'; - case 'DiversionRuleDetectScreen.detect': return '探测'; - case 'DiversionRuleDetectScreen.rule': return '规则:'; - case 'DiversionRuleDetectScreen.outbound': return '代理服务器:'; - case 'DiversionRulesScreen.diversionRulesMatchTips': return '提示:从上到下依次尝试匹配规则,如果没有匹配到规则,则使用[final]'; - case 'DnsSettingsScreen.ispCanNotEmpty': return 'ISP 不能为空'; - case 'DnsSettingsScreen.urlCanNotEmpty': return 'URL 不能为空'; - case 'DnsSettingsScreen.error': return ({required Object p}) => '不支持的类型:${p}'; - case 'DnsSettingsScreen.dnsDesc': return '第一列延迟数据为直连查询延迟;\n第二列:开启[[代理流量]通过代理服务器解析DNS]:延迟数据为通过当前代理服务器转发的查询延迟;未开启[[代理流量]通过代理服务器解析DNS]:延迟数据为直连查询延迟'; - case 'FeedbackScreen.content': return '反馈内容'; - case 'FeedbackScreen.contentHit': return '必填, 最长500字符'; - case 'FeedbackScreen.contentCannotEmpty': return '反馈内容不能为空'; - case 'FileContentViewerScreen.title': return '文件内容查看'; - case 'FileContentViewerScreen.chooseFile': return '选择文件'; - case 'FileContentViewerScreen.clearFileContent': return '确认清空文件内容?'; - case 'FileContentViewerScreen.clearFileContentTips': return '确认清空配置文件内容? 清空配置文件可能会导致数据丢失或应用功能异常, 请谨慎操作'; - case 'HomeScreen.toSelectServer': return '请选择服务器'; - case 'HomeScreen.invalidServer': return '已失效,请重新选择'; - case 'HomeScreen.disabledServer': return '已被禁用,请重新选择'; - case 'HomeScreen.expiredServer': return '无可用服务器:配置可能已过期或被禁用'; - case 'HomeScreen.systemProxyTips': return ({required Object sp, required Object hp}) => 'socks:${sp},http(s):${hp}'; - case 'HomeScreen.trafficTotal': return '总流量'; - case 'HomeScreen.trafficProxy': return '代理流量'; - case 'HomeScreen.myLinkEmpty': return '请先设置[快捷链接]后再使用'; - case 'HomeScreen.deviceNoSpace': return '磁盘空间不足'; - case 'HomeScreen.tooMuchServers': return ({required Object p, required Object p1}) => '代理服务器[${p}>${p1}]过多,可能因系统内存限制而无法连接'; - case 'LaunchFailedScreen.invalidProcess': return '应用启动失败[无效的进程名称],请重新安装应用到独立目录'; - case 'LaunchFailedScreen.invalidProfile': return '应用启动失败[访问配置文件失败],请重新安装应用'; - case 'LaunchFailedScreen.invalidVersion': return '应用启动失败[无效版本],请重新安装应用'; - case 'LaunchFailedScreen.systemVersionLow': return '应用启动失败[系统版本过低]'; - case 'LaunchFailedScreen.startFromUNC': return '无效的安装路径,请重新安装到有效路径'; - case 'MyProfilesEditScreen.title': return '编辑配置'; - case 'MyProfilesEditScreen.urlExist': return 'URL已存在,请使用其他URL'; - case 'MyProfilesEditScreen.updateTimerInterval': return '更新时间间隔'; - case 'MyProfilesEditScreen.updateTimerIntervalTips': return '禁用请设置为:<5m'; - case 'MyProfilesEditScreen.reloadAfterProfileUpdate': return '配置更新后重新加载'; - case 'MyProfilesEditScreen.testLatencyAfterProfileUpdate': return '配置自动更新后启动延迟测试'; - case 'MyProfilesEditScreen.testLatencyAfterProfileUpdateTips': return 'VPN需要处于已连接状态,并且开启[配置更新后重新加载]'; - case 'MyProfilesEditScreen.testLatencyAutoRemove': return '自动移除延迟测试失败的服务器'; - case 'MyProfilesEditScreen.testLatencyAutoRemoveTips': return '最多尝试3次'; - case 'MyProfilesMergeScreen.profilesMerge': return '配置合并'; - case 'MyProfilesMergeScreen.profilesMergeTarget': return '目标配置'; - case 'MyProfilesMergeScreen.profilesMergeSource': return '源配置'; - case 'MyProfilesMergeScreen.profilesMergeTips': return '提示:源配置的分流信息将会被丢弃'; - case 'MyProfilesScreen.title': return '我的配置'; - case 'MyProfilesScreen.atLeastOneEnable': return '无法禁用,请至少保留一个配置可用'; - case 'NetCheckScreen.title': return '网络检测'; - case 'NetCheckScreen.warn': return '注意:由于受网络环境及分流规则等影响,测试结果并不完全等价实际中使用的效果'; - case 'NetCheckScreen.check': return '检测'; - case 'NetCheckScreen.invalidDomain': return '无效域名'; - case 'NetCheckScreen.connectivity': return '网络联通性'; - case 'NetCheckScreen.connectivityTestIpv4AllFailed': return ({required Object p}) => 'Ipv4 连接测试[${p}]全部失败'; - case 'NetCheckScreen.connectivityTestIpv4Ok': return 'Ipv4 连接成功'; - case 'NetCheckScreen.connectivityTestIpv6AllFailed': return ({required Object p}) => 'Ipv6 连接测试[${p}]全部失败, 你的网络可能不支持ipv6'; - case 'NetCheckScreen.connectivityTestIpv6Ok': return 'Ipv6 连接成功'; - case 'NetCheckScreen.connectivityTestOk': return '网络已接入互联网'; - case 'NetCheckScreen.connectivityTestFailed': return '网络尚未接入互联网'; - case 'NetCheckScreen.remoteRulesetsDownloadOk': return '全部下载成功'; - case 'NetCheckScreen.remoteRulesetsDownloadNotOk': return '正在下载或下载失败'; - case 'NetCheckScreen.outbound': return '代理服务器'; - case 'NetCheckScreen.outboundOk': return ({required Object p}) => '[${p}]连接成功'; - case 'NetCheckScreen.outboundFailed': return ({required Object p1, required Object p2}) => '[${p1}]连接失败\n错误:[${p2}]'; - case 'NetCheckScreen.dnsServer': return 'DNS服务器'; - case 'NetCheckScreen.dnsOk': return ({required Object p1, required Object p2, required Object p3, required Object p4}) => '[${p1}]域名解析成功\nDNS规则:[${p2}]\n延迟:[${p3} ms]\n地址:[${p4}]'; - case 'NetCheckScreen.dnsFailed': return ({required Object p1, required Object p2, required Object p3}) => '[${p1}]域名解析失败\n规则:[${p2}]\n错误:[${p3}]'; - case 'NetCheckScreen.host': return 'HTTP连接'; - case 'NetCheckScreen.hostConnection': return ({required Object p1, required Object p2, required Object p3}) => '[${p1}]\n分流规则:[${p2}]\n代理服务器:[${p3}]'; - case 'NetCheckScreen.hostConnectionOk': return '连接成功'; - case 'NetCheckScreen.hostConnectionFailed': return ({required Object p}) => '连接失败:[${p}]'; - case 'NetConnectionsFilterScreen.title': return '连接状态筛选'; - case 'NetConnectionsFilterScreen.hostIp': return '域名/IP'; - case 'NetConnectionsFilterScreen.app': return '应用'; - case 'NetConnectionsFilterScreen.rule': return '规则'; - case 'NetConnectionsFilterScreen.chain': return '出站'; - case 'NetConnectionsScreen.title': return '连接状态'; - case 'NetConnectionsScreen.copyAsCSV': return '已复制为CSV格式'; - case 'NetConnectionsScreen.selectType': return '选择分流类型'; - case 'PerAppAndroidScreen.title': return '分应用代理'; - case 'PerAppAndroidScreen.whiteListMode': return '白名单模式'; - case 'PerAppAndroidScreen.whiteListModeTip': return '启用后:仅代理已勾选的App;未启用:仅代理未勾选的App'; - case 'PerAppAndroidScreen.hideSystemApp': return '隐藏系统应用'; - case 'PerAppAndroidScreen.hideAppIcon': return '隐藏应用图标'; - case 'PerAppAndroidScreen.enableAppQueryPermission': return '开启 [获取应用列表] 权限'; - case 'QrcodeScreen.tooLong': return '文本过长,无法展示'; - case 'QrcodeScreen.copy': return '拷贝链接'; - case 'QrcodeScreen.open': return '打开链接'; - case 'QrcodeScreen.share': return '分享链接'; - case 'QrcodeScreen.shareImage': return '分享二维码'; - case 'RegionSettingsScreen.title': return '国家与地区'; - case 'RegionSettingsScreen.Regions': return '提示:请正确设置你当前所在国家或地区,否则可能会导致分流错误'; - case 'ServerSelectScreen.title': return '选择服务器'; - case 'ServerSelectScreen.autoSelectServer': return '自动选择延迟最低的服务器'; - case 'ServerSelectScreen.recentUse': return '最近使用'; - case 'ServerSelectScreen.myFav': return '我的收藏'; - case 'ServerSelectScreen.selectLocal': return ({required Object p}) => '所选服务器为本地地址,可能无法正常使用:${p}'; - case 'ServerSelectScreen.selectRequireEnableIPv6': return '所选服务器为IPv6地址,需要[启用IPv6]'; - case 'ServerSelectScreen.selectDisabled': return '该服务器已被禁用'; - case 'ServerSelectScreen.error404': return '延迟检测遇到错误,请检查是否存在内容相同的配置'; - case 'SettingsScreen.ispFaq': return ({required Object p}) => 'FAQ[${p}]'; - case 'SettingsScreen.cleanISP': return ({required Object p}) => '清除ISP[${p}]'; - case 'SettingsScreen.openISP': return '打开ISP链接'; - case 'SettingsScreen.cleanISPNoParam': return '清除ISP信息'; - case 'SettingsScreen.getTranffic': return '获取流量'; - case 'SettingsScreen.tutorial': return '使用教程'; - case 'SettingsScreen.commonlyUsedRulesets': return '常用规则集'; - case 'SettingsScreen.howToRemoveAds': return '如何移除广告'; - case 'SettingsScreen.htmlBoard': return '在线面板'; - case 'SettingsScreen.dnsLeakDetection': return 'DNS泄露检测'; - case 'SettingsScreen.speedTest': return '测速'; - case 'SettingsScreen.downloadProfilePreferProxy': return '优先使用代理下载配置'; - case 'SettingsScreen.downloadProfilePreferProxyTips': return '如果当前已连接,则优先通过已连接的代理下载配置'; - case 'SettingsScreen.rulesetDirectDownlad': return 'Rule Set直连下载'; - case 'SettingsScreen.hideUnusedDiversionGroup': return '隐藏未启用的分流组'; - case 'SettingsScreen.disableISPDiversionGroup': return '禁用ISP分流规则'; - case 'SettingsScreen.portSetting': return '端口'; - case 'SettingsScreen.portSettingRule': return '基于规则'; - case 'SettingsScreen.portSettingDirectAll': return '全直连'; - case 'SettingsScreen.portSettingProxyAll': return '全代理'; - case 'SettingsScreen.portSettingControl': return '控制与同步'; - case 'SettingsScreen.portSettingCluster': return '集群服务'; - case 'SettingsScreen.modifyPort': return '修改端口'; - case 'SettingsScreen.ipStrategyTips': return '启用前,请先确认你的网络已支持IPv6,否则某些流量无法正常访问'; - case 'SettingsScreen.tunAppendHttpProxy': return '附加HTTP代理到VPN'; - case 'SettingsScreen.tunAppendHttpProxyTips': return '一些App会绕过虚拟网卡设备直连HTTP代理'; - case 'SettingsScreen.tlsInsecureEnable': return '跳过证书验证'; - case 'SettingsScreen.tlsFragmentEnable': return '启用TLS分段'; - case 'SettingsScreen.tlsFragmentSize': return 'TLS分段大小'; - case 'SettingsScreen.tlsFragmentSleep': return 'TLS分段休眠'; - case 'SettingsScreen.tlsMixedCaseSNIEnable': return '启用TLS混合SNI'; - case 'SettingsScreen.tlsPaddingEnable': return '启用TLS填充'; - case 'SettingsScreen.tlsPaddingSize': return 'TLS填充大小'; - case 'SettingsScreen.dnsEnableRule': return '启用DNS分流规则'; - case 'SettingsScreen.dnsEnableFakeIp': return '启用FakeIP'; - case 'SettingsScreen.dnsEnableClientSubnet': return '启用ECS'; - case 'SettingsScreen.dnsEnableProxyResolveByProxy': return '[代理流量]通过代理服务器解析DNS'; - case 'SettingsScreen.dnsEnableFinalResolveByProxy': return '[final]通过代理服务器解析DNS'; - case 'SettingsScreen.dnsTestDomain': return '测试域名'; - case 'SettingsScreen.dnsTestDomainInvalid': return '无效的域名'; - case 'SettingsScreen.dnsTypeOutbound': return '代理服务器'; - case 'SettingsScreen.dnsTypeDirect': return '直连流量'; - case 'SettingsScreen.dnsTypeProxy': return '代理流量'; - case 'SettingsScreen.dnsTypeResolver': return 'DNS服务器'; - case 'SettingsScreen.dnsEnableRuleTips': return '启用后,域名会根据分流规则选择对应的DNS服务器进行解析'; - case 'SettingsScreen.dnsEnableFakeIpTips': return '启用FakeIP后,如果断开VPN连接,你的应用可能需要重启;此功能需要开启[TUN模式]'; - case 'SettingsScreen.dnsTypeOutboundTips': return '用于代理服务器的域名解析'; - case 'SettingsScreen.dnsTypeDirectTips': return '用于直连流量的域名解析'; - case 'SettingsScreen.dnsTypeProxyTips': return '用于代理流量的域名解析'; - case 'SettingsScreen.dnsTypeResolverTips': return '用于DNS服务器的域名解析'; - case 'SettingsScreen.dnsTypeFinalTips': return '用于其他流量的域名解析'; - case 'SettingsScreen.dnsAutoSetServer': return '自动设置服务器'; - case 'SettingsScreen.dnsResetServer': return '重置服务器'; - case 'SettingsScreen.inboundDomainResolve': return '解析入站域名'; - case 'SettingsScreen.privateDirect': return '私有网络直连'; - case 'SettingsScreen.inboundDomainResolveTips': return ({required Object p}) => '某些未配置分流规则的域名需要解析后才可能命中基于IP的分流规则;此功能影响代理端口[${p}]的入站请求'; - case 'SettingsScreen.useRomoteRes': return '使用远程资源'; - case 'SettingsScreen.autoSelect': return '自动选择'; - case 'SettingsScreen.autoSelectServerIgnorePerProxyServer': return '忽略[前置代理]代理服务器'; - case 'SettingsScreen.autoSelectServerInterval': return '延迟检测时间间隔'; - case 'SettingsScreen.autoSelectServerReTestIfNetworkUpdate': return '网络变化时重新检测'; - case 'SettingsScreen.autoSelectServerUpdateCurrentServerAfterManualUrltest': return '手动延时检测后更新当前服务器'; - case 'SettingsScreen.autoSelectServerIntervalTips': return '延迟检测时间间隔越短,服务器延迟数据更新越及时,但会占用更多资源,耗电更快'; - case 'SettingsScreen.autoSelectServerFavFirst': return '优先使用[我的收藏]'; - case 'SettingsScreen.autoSelectServerFavFirstTips': return '如果[我的收藏]列表不为空,则使用[我的收藏]里的服务器'; - case 'SettingsScreen.autoSelectServerFilter': return '过滤无效服务器'; - case 'SettingsScreen.autoSelectServerFilterTips': return ({required Object p}) => '服务器延迟检测失败的将会被过滤掉;如果过滤后无服务器可用,则改用前[${p}]个服务器'; - case 'SettingsScreen.autoSelectServerLimitedNum': return '服务器数量上限'; - case 'SettingsScreen.autoSelectServerLimitedNumTips': return '超过该数量的服务器将被过滤掉'; - case 'SettingsScreen.numInvalid': return '无效的数字'; - case 'SettingsScreen.hideInvalidServer': return '隐藏无效服务器'; - case 'SettingsScreen.sortServer': return '服务器排序'; - case 'SettingsScreen.sortServerTips': return '按延迟由低到高排序'; - case 'SettingsScreen.selectServerHideRecommand': return '隐藏[推荐]'; - case 'SettingsScreen.selectServerHideRecent': return '隐藏[最近使用]'; - case 'SettingsScreen.selectServerHideFav': return '隐藏[我的收藏]'; - case 'SettingsScreen.homeScreen': return '主屏'; - case 'SettingsScreen.theme': return '主题'; - case 'SettingsScreen.myLink': return '快捷链接'; - case 'SettingsScreen.myLinkInvalid': return '无效的URL'; - case 'SettingsScreen.autoConnectAfterLaunch': return '启动后自动连接'; - case 'SettingsScreen.hideAfterLaunch': return '启动后隐藏窗口'; - case 'SettingsScreen.autoSetSystemProxy': return '连接后自动设置系统代理'; - case 'SettingsScreen.disconnectWhenQuit': return '退出应用时关闭连接'; - case 'SettingsScreen.allowBypass': return '允许应用绕过VPN'; - case 'SettingsScreen.lanSyncTo': return '同步给他人'; - case 'SettingsScreen.lanSyncFrom': return '从他人同步'; - case 'SettingsScreen.lanSyncScanQRcode': return '扫码同步'; - case 'SettingsScreen.syncToConfirm': return '确认同步给对方?'; - case 'SettingsScreen.syncDone': return '同步完成'; - case 'SettingsScreen.importSuccess': return '导入成功'; - case 'SettingsScreen.rewriteConfirm': return '该文件将覆盖本地已有配置,是否继续?'; - case 'SettingsScreen.networkShare': return '网络共享'; - case 'SettingsScreen.frontProxy': return '前置代理'; - case 'SettingsScreen.frontProxyTips': return '数据->前置代理服务器->代理服务器->目标服务器'; - case 'SettingsScreen.allowOtherHostsConnect': return '允许其他主机接入'; - case 'SettingsScreen.allowOtherHostsConnectTips': return ({required Object sp, required Object hp}) => 'socks:${sp},http(s):${hp}'; - case 'SettingsScreen.tunAutoRoute': return 'Auto Route'; - case 'SettingsScreen.tunStrictRoute': return '严格路由'; - case 'SettingsScreen.tunStrictRouteTips': return '如果开启共享后,其他无法接入此设备,请尝试关闭此开关'; - case 'SettingsScreen.enableCluster': return '开启Socks/Http代理集群'; - case 'SettingsScreen.clusterAllowOtherHostsConnect': return '允许其他主机接入代理集群'; - case 'SettingsScreen.clusterAllowOtherHostsConnectTips': return ({required Object hp}) => 'http://127.0.0.1:${hp}/get_proxies'; - case 'SettingsScreen.clusterAuth': return '代理集群认证'; - case 'SettingsScreen.clusterConfirm': return '请确认服务器已经过服务器延迟检测,未检测或者检测出错的将不会创建代理服务'; - case 'SettingsScreen.tunMode': return 'TUN模式'; - case 'SettingsScreen.tunModeTips': return 'TUN模式将接管系统所有流量[此模式下无需开启系统代理]'; - case 'SettingsScreen.tunModeRunAsAdmin': return 'TUN模式需要系统管理员权限,请以管理员身份重新启动应用'; - case 'SettingsScreen.tunStack': return '网络栈'; - case 'SettingsScreen.launchAtStartup': return '开机启动'; - case 'SettingsScreen.quitWhenSwitchSystemUser': return '切换系统用户时退出应用'; - case 'SettingsScreen.handleScheme': return '系统Scheme调用'; - case 'SettingsScreen.portableMode': return '便携模式'; - case 'SettingsScreen.portableModeDisableTips': return '如需退出便携模式,请退出[karing]后,手动删除[karing.exe]同目录下的[profiles]文件夹即可'; - case 'SettingsScreen.handleKaringScheme': return '处理karing://调用'; - case 'SettingsScreen.handleClashScheme': return '处理clash://调用'; - case 'SettingsScreen.handleSingboxScheme': return '处理sing-box://调用'; - case 'SettingsScreen.removeSystemVPNConfig': return '删除系统VPN配置'; - case 'SettingsScreen.timeConnectOrDisconnect': return '定时连接/断开'; - case 'SettingsScreen.timeConnectOrDisconnectTips': return 'VPN必须处于连接状态才会生效;开启后,[自动休眠]将失效'; - case 'SettingsScreen.timeConnectAndDisconnectInterval': return ({required Object p}) => '连接/断开时间间隔不能低于${p}分钟'; - case 'SettingsScreen.disableFontScaler': return '禁用字体缩放'; - case 'SettingsScreen.autoOrientation': return '跟随屏幕旋转'; - case 'SettingsScreen.restartTakesEffect': return '重启生效'; - case 'SettingsScreen.resetSettings': return '重置设置'; - case 'SettingsScreen.cleanCache': return '清理缓存'; - case 'SettingsScreen.cleanCacheDone': return '清理完成'; - case 'SettingsScreen.appleTestFlight': return '苹果 TestFlight'; - case 'SettingsScreen.appleAppStore': return '苹果 AppStore'; - case 'SettingsScreen.hasNewVersion': return ({required Object p}) => '更新版本 ${p}'; - case 'SettingsScreen.follow': return '关注我们'; - case 'SettingsScreen.contactUs': return '联系我们'; - case 'SettingsScreen.rateInApp': return '评分'; - case 'SettingsScreen.rateInAppStore': return '在App Store上评分'; - case 'SpeedTestSettingsScreen.title': return '测速URL'; - case 'SpeedTestSettingsScreen.error': return '必须为有效的 https URL'; - case 'TextToQrCodeScreen.title': return '文本转二维码'; - case 'TextToQrCodeScreen.convert': return '转换'; - case 'UrlTestSettingsScreen.title': return '延迟检测URL'; - case 'UrlTestSettingsScreen.error': return '必须为有效的 https URL'; - case 'UserAgreementScreen.privacyFirst': return '您的隐私很重要'; - case 'UserAgreementScreen.agreeAndContinue': return '接受并继续'; - case 'VersionUpdateScreen.versionReady': return ({required Object p}) => '新版本[${p}]已就绪'; - case 'VersionUpdateScreen.update': return '重启更新'; - case 'VersionUpdateScreen.cancel': return '暂不更新'; - case 'CommonWidget.diableAlwayOnVPN': return '如果开启了[始终开启VPN], 请关闭[始终开启VPN]后重试连接'; - case 'CommonWidget.resetPort': return '请将端口改为其他可用端口或者关闭占用该端口的应用'; - case 'ServerManager.noServerAvaliable': return '无可用服务器,请确保配置链接或配置文件有效;如果你的配置来源于GitHub,请从页面上的[Raw]按钮获取链接地址'; - case 'ServerManager.filePathCannotEmpty': return '文件路径不能为空'; - case 'ServerManager.fileNotExist': return ({required Object p}) => '文件不存在:${p}'; - case 'ServerManager.urlCannotEmpty': return '链接不能为空'; - case 'ServerManager.invalidUrl': return '错误的配置链接'; - case 'ServerManager.parseFailed': return '解析配置失败'; - case 'main.tray.menuOpen': return ' 打开 '; - case 'main.tray.menuExit': return ' 退出 '; - case 'enable': return '启用'; - case 'disable': return '禁用'; - case 'prefer': return '优先'; - case 'only': return '仅'; - case 'open': return '打开'; - case 'close': return '关闭'; - case 'quit': return '退出'; - case 'add': return '添加'; - case 'remove': return '删除'; - case 'edit': return '编辑'; - case 'view': return '查看'; - case 'more': return '更多'; - case 'addProfile': return '添加配置'; - case 'addSuccess': return '添加成功'; - case 'addSuccessThen': return ({required Object p}) => '配置生成成功,请到[${p}]查看'; - case 'addFailed': return ({required Object p}) => '添加失败:${p}'; - case 'removeConfirm': return '确认删除?'; - case 'tips': return '提示'; - case 'copy': return '拷贝'; - case 'ok': return '确定'; - case 'cancel': return '取消'; - case 'feedback': return '反馈'; - case 'faq': return '常见问题'; - case 'download': return '下载'; - case 'loading': return '加载中...'; - case 'updateFailed': return ({required Object p}) => '更新失败:${p}'; - case 'days': return '天'; - case 'hours': return '时'; - case 'minutes': return '分'; - case 'seconds': return '秒'; - case 'protocol': return '协议'; - case 'search': return '搜索'; - case 'custom': return '自定义'; - case 'connect': return '连接'; - case 'disconnect': return '断开'; - case 'connected': return '已连接'; - case 'disconnected': return '未连接'; - case 'connecting': return '连接中'; - case 'connectTimeout': return '连接超时'; - case 'timeout': return '超时'; - case 'language': return '语言'; - case 'next': return '下一步'; - case 'done': return '完成'; - case 'apply': return '应用'; - case 'refresh': return '刷新'; - case 'retry': return '是否重试?'; - case 'none': return '无'; - case 'reset': return '重置'; - case 'submit': return '提交'; - case 'account': return '账号'; - case 'password': return '密码'; - case 'required': return '必填'; - case 'diversion': return '分流'; - case 'diversionRules': return '分流规则'; - case 'diversionRulesEnable': return '启用[ISP]分流规则'; - case 'diversionCustomGroup': return '自定义分流组'; - case 'diversionCustomGroupPreset': return '预置[自定义分流组]'; - case 'diversionCustomGroupPresetTips': return '注意:启用的项会添加/覆盖到[自定义分流组]和[分流规则]'; - case 'diversionCustomGroupAddTips': return '注意:添加完毕后可能需要手动调整排序,否则新添加的分流可能不会生效'; - case 'urlTestCustomGroup': return '自定义代理组'; - case 'rulesetEnableTips': return '提示:开启选项后,请到[分流规则]设置相关规则,否则不会生效'; - case 'ispUserAgentTips': return '[ISP]会根据[HTTP]请求里的[UserAgent]下发不同订阅类型的数据'; - case 'ispDiversionTips': return '[ISP]提供的分流规则;[V2Ray]类型的订阅不支持分流规则'; - case 'staticIP': return '静态IP'; - case 'other': return '其他'; - case 'dns': return 'DNS'; - case 'url': return 'URL'; - case 'isp': return 'ISP'; - case 'tls': return 'TLS'; - case 'userAgent': return 'UserAgent'; - case 'urlInvalid': return '无效URL'; - case 'outboundActionCurrentSelected': return '当前选择'; - case 'outboundActionUrltest': return '自动选择'; - case 'outboundActionDirect': return '直连'; - case 'outboundActionBlock': return '拦截'; - case 'routeFinal': return 'final'; - case 'rulesetGeoSite': return 'GeoSite'; - case 'rulesetGeoIp': return 'GeoIP'; - case 'rulesetAcl': return 'ACL'; - case 'iCloud': return 'iCloud'; - case 'appleTV': return 'Apple TV'; - case 'webdav': return 'Webdav'; - case 'setting': return '设置'; - case 'protocolSniff': return '协议探测'; - case 'protocolSniffOverrideDestination': return '探测的域名覆盖连接目标地址'; - case 'remark': return '备注'; - case 'remarkCannotEmpty': return '备注不能为空'; - case 'remarkTooLong': return '备注最长32字符'; - case 'remarkExist': return '备注已存在,请使用其他名称'; - case 'domainSuffix': return '域名后缀'; - case 'domain': return '域名'; - case 'domainKeyword': return '域名关键词'; - case 'domainRegex': return '域名正则'; - case 'ip': return 'IP'; - case 'port': return '端口'; - case 'appPackage': return '应用包名'; - case 'processName': return '进程名称'; - case 'processPath': return '进程路径'; - case 'systemProxy': return '系统代理'; - case 'netInterfaces': return '网络接口'; - case 'netSpeed': return '速度'; - case 'website': return '官网'; - case 'rule': return '规则'; - case 'global': return '全局'; - case 'qrcode': return '二维码'; - case 'scanQrcode': return '扫描二维码'; - case 'scanResult': return '扫描结果'; - case 'backupAndSync': return '备份与同步'; - case 'importAndExport': return '导入/导出'; - case 'import': return '导入'; - case 'export': return '导出'; - case 'termOfUse': return '使用条款'; - case 'privacyPolicy': return '隐私政策'; - case 'about': return '关于'; - case 'name': return '名称'; - case 'version': return '版本'; - case 'notice': return '通知'; - case 'sort': return '排序'; - case 'novice': return '新手模式'; - case 'recommended': return '推荐'; - case 'innerError': return ({required Object p}) => '内部错误:${p}'; - case 'logicOperation': return '逻辑运算'; - case 'share': return '分享'; - case 'candidateWord': return '候选词'; - case 'keywordsOrRegx': return '关键词/正则'; - case 'importFromClipboard': return '从剪切板导入'; - case 'exportToClipboard': return '导出到剪切板'; - case 'server': return '服务器'; - case 'appleTVConnectTurnOfprivateDirect': return '请先开启[私有网络直连]'; - case 'targetConnectFailed': return ({required Object p}) => '连接[${p}]失败,请确保设备在同一个局域网内,并且开启[私有网络直连]'; - case 'appleTVSync': return '同步当前核心配置到Apple TV - Karing'; - case 'appleTVSyncDone': return '同步完成,请到Apple TV - Karing开启连接/重启连接'; - case 'appleTVRemoveCoreConfig': return '删除Apple TV - Karing核心配置'; - case 'appleTVRemoveCoreConfigDone': return 'Apple TV - Karing的核心配置文件已删除;VPN服务已断开连接'; - case 'appleTVUrlInvalid': return '无效的URL,请打开Apple TV - Karing,扫描Karing显示的二维码'; - case 'remoteProfileEditConfirm': return '配置更新后,节点的修改将会被还原,是否继续?'; - case 'invalidFileType': return ({required Object p}) => '无效的文件类型:${p}'; - case 'locales.en': return 'English'; - case 'locales.zh-CN': return '简体中文'; - case 'locales.ar': return 'عربي'; - case 'locales.ru': return 'Русский'; - case 'locales.fa': return 'فارسی'; - default: return null; - } - } -} diff --git a/lib/i18n/strings.i18n.json b/lib/i18n/strings.i18n.json index cfe0b3c..9451e53 100644 --- a/lib/i18n/strings.i18n.json +++ b/lib/i18n/strings.i18n.json @@ -20,7 +20,7 @@ "AddProfileByLinkOrContentScreen": { "title": "Add Profile Link", "updateTimerInterval": "Update interval", - "updateTimerIntervalTips": "To disable please set to:<5m", + "updateTimerIntervalTips": "Minimum: 5m", "profileLinkContent": "Profile Link/Content", "profileLinkContentHit": "Profile Link/Content [Required] (Support Clash,V2ray(batch supported),Stash,Karing,Sing-box,Shadowsocks,Sub Profile links)", "subscriptionCannotEmpty": "Profile Link can not be empty", @@ -102,13 +102,13 @@ "invalidProfile": "The app failed to start [Failed to access the profile], please reinstall the app", "invalidVersion": "The app failed to start [Invalid version], please reinstall the app", "systemVersionLow": "The app failed to start [system version too low]", - "startFromUNC": "The installation path is invalid, please reinstall it to a valid path" + "invalidInstallPath": "The installation path is invalid, please reinstall it to a valid path" }, "MyProfilesEditScreen": { "title": "Profile Edit", "urlExist": "URL already exists, please use another URL", "updateTimerInterval": "Update interval", - "updateTimerIntervalTips": "To disable please set to:<5m", + "updateTimerIntervalTips": "Minimum: 5m", "reloadAfterProfileUpdate": "Reload after Profile update", "testLatencyAfterProfileUpdate": "Start latency tests after Profile Automatically update", "testLatencyAfterProfileUpdateTips": "VPN needs to be connected, and [Reload after Profile update] Enabled", @@ -215,6 +215,7 @@ "portSettingControl": "Control and Sync", "portSettingCluster": "Cluster Service", "modifyPort": "Modify Port", + "modifyPortOccupied": "The port is occupied, please use another port", "ipStrategyTips": "Before enabling, please confirm that your network supports IPv6, otherwise some traffic cannot be accessed normally.", "tunAppendHttpProxy": "Append HTTP Proxy to VPN", "tunAppendHttpProxyTips": "Some apps will bypass virtual NIC Device and directly connect to HTTP proxy", @@ -277,16 +278,11 @@ "autoSetSystemProxy": "Auto Set System Proxy when Connected", "disconnectWhenQuit": "Disconnect when App Exits", "allowBypass": "Allow Apps to Bypass VPN", - "lanSyncTo": "Sync to others", - "lanSyncFrom": "Sync from others", - "lanSyncScanQRcode": "Scan QR code to Sync", - "syncToConfirm": "Confirm sync to the other party?", - "syncDone": "Sync completed", "importSuccess": "Import Success", "rewriteConfirm": "This file will overwrite the existing local configuration. Do you want to continue?", "networkShare": "Network Sharing", "frontProxy": "Per-Proxy", - "frontProxyTips": "Data->Per-Proxy server->Proxy server->Target server", + "frontProxyTips": "Data->Pre-Proxy Server [Multiple Pre-Proxy Servers: from top to bottom]->Proxy Server [$p]->Target Server", "allowOtherHostsConnect": "Allow Others to Connect", "allowOtherHostsConnectTips": "socks:$sp,http(s):$hp", "tunAutoRoute": "Auto Route", @@ -294,9 +290,8 @@ "tunStrictRouteTips": "If after turning on sharing, others cannot access this device, please try turning off this switch", "enableCluster": "Enable Socks/Http Proxy Cluster", "clusterAllowOtherHostsConnect": "Allow Others to Connect to Cluster", - "clusterAllowOtherHostsConnectTips": "http://127.0.0.1:$hp/get_proxies", + "clusterAllowOtherHostsConnectTips": "http://$ip:$port/get_proxies", "clusterAuth": "Proxy Cluster Authentication", - "clusterConfirm": "Please confirm that the servers latency have been checked, and proxy services will not be created if they are not checked or checked incorrectly", "tunMode": "TUN Mode", "tunModeTips": "The TUN mode will take over all the traffic of the system [In this mode, you can leave the system proxy unenabled]", "tunModeRunAsAdmin": "The TUN mode requires system administrator permissions, please restart the app as an administrator", @@ -309,6 +304,7 @@ "handleKaringScheme": "Handle karing:// Call", "handleClashScheme": "Handle clash:// Call", "handleSingboxScheme": "Handle sing-box:// Call", + "alwayOnVPN": "Always-on Connection", "removeSystemVPNConfig": "Delete system VPN configuration", "timeConnectOrDisconnect": "Scheduled connect/disconnect", "timeConnectOrDisconnectTips": "VPN must be connected to take effect; after it is turned on, [Automatic Sleep] will be disabled", @@ -328,17 +324,12 @@ "rateInAppStore": "Rate Us in AppStore" }, "SpeedTestSettingsScreen": { - "title": "Speed Test URL", - "error": "Must be Valid https URL" + "title": "Speed Test URL" }, "TextToQrCodeScreen": { "title": "Text To QR Code", "convert": "Convert" }, - "UrlTestSettingsScreen": { - "title": "Latency Checks URL", - "error": "Must be Valid https URL" - }, "UserAgreementScreen": { "privacyFirst": "Your Privacy Comes First", "agreeAndContinue": "Accept & Continue" @@ -368,6 +359,11 @@ }, "enable": "Enable", "disable": "Disable", + "filter": "Filter", + "filterMethod": "Filter Method", + "include": "Include", + "exclude": "Exclude", + "all": "All", "prefer": "Prefer", "only": "Only", "open": "Open", @@ -477,6 +473,10 @@ "importAndExport": "Import and Export", "import": "Import", "export": "Export", + "send": "Send", + "receive": "Receive", + "sendOrReceiveNotMatch": "Please use [$p]", + "sendConfirm": "Confirm to send?", "termOfUse": "Terms of Service", "privacyPolicy": "Privacy & Policy", "about": "About", @@ -490,7 +490,7 @@ "logicOperation": "Logic Operation", "share": "Share", "candidateWord": "Candidate Words", - "keywordsOrRegx": "Keywords/Regular", + "keywordOrRegx": "Keywords/Regular", "importFromClipboard": "Import From Clipboard", "exportToClipboard": "Export to Clipboard", "server": "Server", @@ -503,6 +503,14 @@ "appleTVUrlInvalid": "Invalid URL, please open Apple TV - Karing and scan the QR code displayed by Karing", "remoteProfileEditConfirm": "After the Profile is updated, the node changes will be restored. Continue?", "invalidFileType": "Invalid file type:$p", + "mustBeValidHttpsURL": "Must be Valid https URL", + "fileNotExistReinstall": "File missing [$p], please reinstall", + "latencyTest": "Latency Checks", + "latencyTestResolveIP": "When manually checking, resolve the outlet IP", + "uwpExemption": "UWP Network Isolation Exemptions", + "removeBannerAds": "Remove ads", + "removeBannerAdsByReward": "Watch a few seconds of advertising and you will get 7 days of ad-free rewards", + "removeBannerAdsByRewardDone": "Received 7 days of ad-free reward", "locales(map)": { "en": "English", "zh-CN": "简体中文", diff --git a/lib/i18n/strings_ar.g.dart b/lib/i18n/strings_ar.g.dart new file mode 100644 index 0000000..fdad7b3 --- /dev/null +++ b/lib/i18n/strings_ar.g.dart @@ -0,0 +1,1281 @@ +/// +/// Generated file. Do not edit. +/// +// coverage:ignore-file +// ignore_for_file: type=lint, unused_import + +import 'package:flutter/widgets.dart'; +import 'package:intl/intl.dart'; +import 'package:slang/generated.dart'; +import 'strings.g.dart'; + +// Path: +class TranslationsAr implements Translations { + /// You can call this constructor and build your own translation instance of this locale. + /// Constructing via the enum [AppLocale.build] is preferred. + TranslationsAr({Map? overrides, PluralResolver? cardinalResolver, PluralResolver? ordinalResolver}) + : assert(overrides == null, 'Set "translation_overrides: true" in order to enable this feature.'), + $meta = TranslationMetadata( + locale: AppLocale.ar, + overrides: overrides ?? {}, + cardinalResolver: cardinalResolver, + ordinalResolver: ordinalResolver, + ) { + $meta.setFlatMapFunction(_flatMapFunction); + } + + /// Metadata for the translations of . + @override final TranslationMetadata $meta; + + /// Access flat map + @override dynamic operator[](String key) => $meta.getTranslation(key); + + late final TranslationsAr _root = this; // ignore: unused_field + + // Translations + @override late final _TranslationsAboutScreenAr AboutScreen = _TranslationsAboutScreenAr._(_root); + @override late final _TranslationsAddProfileByImportFromFileScreenAr AddProfileByImportFromFileScreen = _TranslationsAddProfileByImportFromFileScreenAr._(_root); + @override late final _TranslationsAddProfileByLinkOrContentScreenAr AddProfileByLinkOrContentScreen = _TranslationsAddProfileByLinkOrContentScreenAr._(_root); + @override late final _TranslationsAddProfileByScanQrcodeScanScreenAr AddProfileByScanQrcodeScanScreen = _TranslationsAddProfileByScanQrcodeScanScreenAr._(_root); + @override late final _TranslationsBackupAndSyncLanSyncScreenAr BackupAndSyncLanSyncScreen = _TranslationsBackupAndSyncLanSyncScreenAr._(_root); + @override late final _TranslationsBackupAndSyncWebdavScreenAr BackupAndSyncWebdavScreen = _TranslationsBackupAndSyncWebdavScreenAr._(_root); + @override late final _TranslationsDiversionGroupCustomEditScreenAr DiversionGroupCustomEditScreen = _TranslationsDiversionGroupCustomEditScreenAr._(_root); + @override late final _TranslationsDiversionRuleDetectScreenAr DiversionRuleDetectScreen = _TranslationsDiversionRuleDetectScreenAr._(_root); + @override late final _TranslationsDiversionRulesScreenAr DiversionRulesScreen = _TranslationsDiversionRulesScreenAr._(_root); + @override late final _TranslationsDnsSettingsScreenAr DnsSettingsScreen = _TranslationsDnsSettingsScreenAr._(_root); + @override late final _TranslationsFeedbackScreenAr FeedbackScreen = _TranslationsFeedbackScreenAr._(_root); + @override late final _TranslationsFileContentViewerScreenAr FileContentViewerScreen = _TranslationsFileContentViewerScreenAr._(_root); + @override late final _TranslationsHomeScreenAr HomeScreen = _TranslationsHomeScreenAr._(_root); + @override late final _TranslationsLaunchFailedScreenAr LaunchFailedScreen = _TranslationsLaunchFailedScreenAr._(_root); + @override late final _TranslationsMyProfilesEditScreenAr MyProfilesEditScreen = _TranslationsMyProfilesEditScreenAr._(_root); + @override late final _TranslationsMyProfilesMergeScreenAr MyProfilesMergeScreen = _TranslationsMyProfilesMergeScreenAr._(_root); + @override late final _TranslationsMyProfilesScreenAr MyProfilesScreen = _TranslationsMyProfilesScreenAr._(_root); + @override late final _TranslationsNetCheckScreenAr NetCheckScreen = _TranslationsNetCheckScreenAr._(_root); + @override late final _TranslationsNetConnectionsFilterScreenAr NetConnectionsFilterScreen = _TranslationsNetConnectionsFilterScreenAr._(_root); + @override late final _TranslationsNetConnectionsScreenAr NetConnectionsScreen = _TranslationsNetConnectionsScreenAr._(_root); + @override late final _TranslationsPerAppAndroidScreenAr PerAppAndroidScreen = _TranslationsPerAppAndroidScreenAr._(_root); + @override late final _TranslationsQrcodeScreenAr QrcodeScreen = _TranslationsQrcodeScreenAr._(_root); + @override late final _TranslationsRegionSettingsScreenAr RegionSettingsScreen = _TranslationsRegionSettingsScreenAr._(_root); + @override late final _TranslationsServerSelectScreenAr ServerSelectScreen = _TranslationsServerSelectScreenAr._(_root); + @override late final _TranslationsSettingsScreenAr SettingsScreen = _TranslationsSettingsScreenAr._(_root); + @override late final _TranslationsSpeedTestSettingsScreenAr SpeedTestSettingsScreen = _TranslationsSpeedTestSettingsScreenAr._(_root); + @override late final _TranslationsTextToQrCodeScreenAr TextToQrCodeScreen = _TranslationsTextToQrCodeScreenAr._(_root); + @override late final _TranslationsUserAgreementScreenAr UserAgreementScreen = _TranslationsUserAgreementScreenAr._(_root); + @override late final _TranslationsVersionUpdateScreenAr VersionUpdateScreen = _TranslationsVersionUpdateScreenAr._(_root); + @override late final _TranslationsCommonWidgetAr CommonWidget = _TranslationsCommonWidgetAr._(_root); + @override late final _TranslationsServerManagerAr ServerManager = _TranslationsServerManagerAr._(_root); + @override late final _TranslationsMainAr main = _TranslationsMainAr._(_root); + @override String get enable => 'يُمكَِن'; + @override String get disable => 'إبطال'; + @override String get filter => 'فلتر'; + @override String get filterMethod => 'طريقة التصفية'; + @override String get include => 'يشمل'; + @override String get exclude => 'استبعاد'; + @override String get all => 'الجميع'; + @override String get prefer => 'أولوية'; + @override String get only => 'فقط'; + @override String get open => 'يفتح'; + @override String get close => 'إنهاء'; + @override String get quit => 'يترك'; + @override String get add => 'اضف إليه'; + @override String get remove => 'يمسح'; + @override String get edit => 'يحرر'; + @override String get view => 'يفحص'; + @override String get more => 'أكثر'; + @override String get addProfile => 'إضافة ملف تعريف'; + @override String get addSuccess => 'اضيف بنجاح'; + @override String addSuccessThen({required Object p}) => 'تم إنشاء التكوين بنجاح، يرجى الانتقال إلى [${p}] للعرض'; + @override String addFailed({required Object p}) => 'إضافة فشل:${p}'; + @override String get removeConfirm => 'هل انت متأكد من الحذف؟'; + @override String get tips => 'معلومات'; + @override String get copy => 'ينسخ'; + @override String get ok => 'نعم'; + @override String get cancel => 'يلغي'; + @override String get feedback => 'تعليق'; + @override String get faq => 'أسئلة مكررة'; + @override String get download => 'تحميل'; + @override String get loading => 'تحميل...'; + @override String updateFailed({required Object p}) => 'فشل التحديث:${p}'; + @override String get days => 'أيام'; + @override String get hours => 'ساعات'; + @override String get minutes => 'دقائق'; + @override String get seconds => 'ثانية'; + @override String get protocol => 'بروتوكول'; + @override String get search => 'يبحث'; + @override String get custom => 'مخصص'; + @override String get connect => 'يتصل'; + @override String get disconnect => 'قطع الاتصال'; + @override String get connected => 'متصل'; + @override String get disconnected => 'انقطع الاتصال'; + @override String get connecting => 'توصيل'; + @override String get connectTimeout => 'ربط مهلة'; + @override String get timeout => 'نفذ الوقت'; + @override String get language => 'لغة'; + @override String get next => 'التالي'; + @override String get done => 'منتهي'; + @override String get apply => 'يتقدم'; + @override String get refresh => 'ينعش'; + @override String get retry => 'إعادة المحاولة?'; + @override String get none => 'لا أحد'; + @override String get reset => 'إعادة ضبط'; + @override String get submit => 'يُقدِّم'; + @override String get account => 'حساب'; + @override String get password => 'كلمة المرور'; + @override String get required => 'مطلوب'; + @override String get diversion => 'تحويل'; + @override String get diversionRules => 'قواعد التحويل'; + @override String get diversionRulesEnable => 'تمكين قواعد تفريغ [ISP]'; + @override String get diversionCustomGroup => 'مجموعة تحويل مخصصة'; + @override String get diversionCustomGroupPreset => 'الإعداد المسبق [مجموعة تحويل مخصصة]'; + @override String get diversionCustomGroupPresetTips => 'ملاحظة: ستتم إضافة/تغطية العناصر الممكّنة إلى [مجموعة التحويل المخصصة] و[قواعد التحويل]'; + @override String get diversionCustomGroupAddTips => 'ملاحظة: قد تحتاج إلى ضبط الفرز يدويًا بعد إضافته، وإلا فإن التحويل المضاف حديثًا قد لا يسري مفعوله.'; + @override String get urlTestCustomGroup => 'مجموعة الوكيل المخصصة'; + @override String get rulesetEnableTips => 'نصيحة: بعد تشغيل الخيارات ، يرجى الانتقال إلى [قواعد التحويل] لتعيين القواعد ذات الصلة ، وإلا فلن تدخل ساري المفعول '; + @override String get ispUserAgentTips => 'سيقدم [ISP] أنواعًا مختلفة من بيانات الاشتراك بناءً على [UserAgent] في طلب [HTTP].'; + @override String get ispDiversionTips => 'قواعد التفريغ التي يوفرها [ISP]؛ لا تدعم الاشتراكات من النوع [V2Ray] قواعد التفريغ'; + @override String get staticIP => 'رقم تعريف حاسوب ثابت'; + @override String get other => 'آخر'; + @override String get dns => 'DNS'; + @override String get url => 'URL'; + @override String get isp => 'ISP'; + @override String get tls => 'TLS'; + @override String get userAgent => 'UserAgent'; + @override String get urlInvalid => 'URL غير صالح'; + @override String get outboundActionCurrentSelected => 'المحدد الحالي'; + @override String get outboundActionUrltest => 'اختيار آلي'; + @override String get outboundActionDirect => 'مباشر'; + @override String get outboundActionBlock => 'حاجز'; + @override String get routeFinal => 'أخير'; + @override String get rulesetGeoSite => 'GeoSite'; + @override String get rulesetGeoIp => 'GeoIP'; + @override String get rulesetAcl => 'ACL'; + @override String get iCloud => 'iCloud'; + @override String get appleTV => 'Apple TV'; + @override String get webdav => 'Webdav'; + @override String get setting => 'إعدادات'; + @override String get protocolSniff => 'الكشف عن البروتوكول'; + @override String get protocolSniffOverrideDestination => 'يغطي اسم المجال المكتشف عنوان هدف الاتصال'; + @override String get remark => 'ملاحظة'; + @override String get remarkCannotEmpty => 'لا يمكن أن تكون الملاحظات فارغة'; + @override String get remarkTooLong => 'ملاحظات تصل إلى 32 حرفًا'; + @override String get remarkExist => 'ملاحظة موجودة بالفعل ، يرجى استخدام اسم آخر'; + @override String get domainSuffix => 'لاحقة اسم المجال'; + @override String get domain => 'اسم النطاق'; + @override String get domainKeyword => 'الكلمات الرئيسية لاسم المجال'; + @override String get domainRegex => 'انتظام اسم المجال'; + @override String get ip => 'IP'; + @override String get port => 'ميناء'; + @override String get appPackage => 'اسم حزمة التطبيق'; + @override String get processName => 'اسم العملية'; + @override String get processPath => 'مسار العملية'; + @override String get systemProxy => 'وكيل النظام'; + @override String get netInterfaces => 'واجهات صافية'; + @override String get netSpeed => 'سرعة'; + @override String get website => 'موقع إلكتروني'; + @override String get rule => 'قاعدة'; + @override String get global => 'عالمي'; + @override String get qrcode => 'رمز الاستجابة السريعة'; + @override String get scanQrcode => 'مسح رمز الاستجابة السريعة'; + @override String get scanResult => 'نتيجة المسح'; + @override String get backupAndSync => 'النسخ الاحتياطي والمزامنة'; + @override String get importAndExport => 'استيراد وتصدير'; + @override String get import => 'يستورد'; + @override String get export => 'يصدّر'; + @override String get send => 'يرسل'; + @override String get receive => 'تولي'; + @override String sendOrReceiveNotMatch({required Object p}) => 'الرجاء استخدام [${p}]'; + @override String get sendConfirm => 'تأكيد الإرسال؟'; + @override String get termOfUse => 'شرط الخدمة'; + @override String get privacyPolicy => 'سياسة الخصوصية'; + @override String get about => 'عن'; + @override String get name => 'اسم'; + @override String get version => 'إصدار'; + @override String get notice => 'يلاحظ'; + @override String get sort => 'إعادة ترتيب'; + @override String get novice => 'وضع المبتدئ'; + @override String get recommended => 'يوصي'; + @override String innerError({required Object p}) => 'خطأ داخلي: ${p}'; + @override String get logicOperation => 'عملية منطقية'; + @override String get share => 'يشارك'; + @override String get candidateWord => 'كلمات المرشح'; + @override String get keywordOrRegx => 'الكلمات الرئيسية/العادية'; + @override String get importFromClipboard => 'استيراد من الحافظة'; + @override String get exportToClipboard => 'تصدير إلى الحافظة'; + @override String get server => 'الخادم'; + @override String get appleTVConnectTurnOfprivateDirect => 'يرجى تمكين [الاتصال المباشر بالشبكة الخاصة] أولاً'; + @override String targetConnectFailed({required Object p}) => 'فشل الاتصال بـ [${p}]، يرجى التأكد من وجود الجهاز في نفس الشبكة المحلية (LAN) وتمكين [الاتصال المباشر بالشبكة الخاصة]'; + @override String get appleTVSync => 'مزامنة التكوين الأساسي الحالي مع Apple TV - Karing'; + @override String get appleTVSyncDone => 'اكتملت المزامنة، برجاء الانتقال إلى Apple TV - Karing لفتح/إعادة تشغيل الاتصال'; + @override String get appleTVRemoveCoreConfig => 'إزالة Apple TV - Karing Core Configuration'; + @override String get appleTVRemoveCoreConfigDone => 'Apple TV - تم حذف الملف التعريفي الأساسي لـ Karing؛ وتم قطع اتصال خدمة VPN'; + @override String get appleTVUrlInvalid => 'عنوان URL غير صالح، يرجى فتح Apple TV - Karing، ومسح رمز QR الذي يعرضه Karing'; + @override String get remoteProfileEditConfirm => 'بعد تحديث التكوين، ستتم استعادة تعديلات العقدة. هل تريد المتابعة؟'; + @override String invalidFileType({required Object p}) => 'نوع الملف غير صالح:${p}'; + @override String get mustBeValidHttpsURL => 'يجب أن يكون عنوان URL HTTPS صالح'; + @override String fileNotExistReinstall({required Object p}) => 'الملف مفقود [${p}]، يرجى إعادة التثبيت'; + @override String get latencyTest => 'كشف التأخير'; + @override String get latencyTestResolveIP => 'أثناء الكشف اليدوي، يتم أيضًا تحليل عنوان IP الخاص بالتصدير.'; + @override String get uwpExemption => 'إعفاء عزل شبكة UWP'; + @override String get removeBannerAds => 'إزالة الإعلانات'; + @override String get removeBannerAdsByReward => 'شاهد بضع ثوانٍ من الإعلانات التجارية وستتم مكافأتك بـ 7 أيام من عدم وجود إعلانات تجارية'; + @override String get removeBannerAdsByRewardDone => 'حصلت على مكافأة خالية من الإعلانات لمدة 7 أيام'; + @override Map get locales => { + 'en': 'English', + 'zh-CN': '简体中文', + 'ar': 'عربي', + 'ru': 'Русский', + 'fa': 'فارسی', + }; +} + +// Path: AboutScreen +class _TranslationsAboutScreenAr implements TranslationsAboutScreenEn { + _TranslationsAboutScreenAr._(this._root); + + final TranslationsAr _root; // ignore: unused_field + + // Translations + @override String get installRefer => 'تثبيت الرجوع'; + @override String get versionChannel => 'تحديث القنوات تلقائيا'; + @override String get disableUAReport => 'قم بإيقاف تشغيل تقرير بيانات الإجراء'; + @override String get disableUAReportTip => 'تساعدنا تقارير البيانات السلوكية على تحسين تجربة المنتج؛ ستقوم الإصدارات الأقل من الإصدار الرئيسي بإيقاف تشغيل جميع تقارير البيانات تلقائيًا (باستثناء [تنشيط التطبيق])'; + @override String get devOptions => 'خيارات للمطور'; + @override String get enableDebugLog => 'تمكين سجل التصحيح'; + @override String get viewFilsContent => 'عرض الملفات'; + @override String get enablePprof => 'يُمكَِن pprof'; + @override String get pprofPanel => 'pprof لوحة'; + @override String get openDir => 'فتح دليل الملف'; + @override String get useOriginalSBProfile => 'استخدم تكوين صندوق الغناء الأصلي'; +} + +// Path: AddProfileByImportFromFileScreen +class _TranslationsAddProfileByImportFromFileScreenAr implements TranslationsAddProfileByImportFromFileScreenEn { + _TranslationsAddProfileByImportFromFileScreenAr._(this._root); + + final TranslationsAr _root; // ignore: unused_field + + // Translations + @override String get title => 'استيراد ملف الملف الشخصي'; + @override String get chooseFile => 'حدد الملف'; + @override String get configExist => 'الملف الشخصي موجود بالفعل ، من فضلك لا تضيفه مرارًا وتكرارًا'; +} + +// Path: AddProfileByLinkOrContentScreen +class _TranslationsAddProfileByLinkOrContentScreenAr implements TranslationsAddProfileByLinkOrContentScreenEn { + _TranslationsAddProfileByLinkOrContentScreenAr._(this._root); + + final TranslationsAr _root; // ignore: unused_field + + // Translations + @override String get title => 'إضافة رابط ملف التعريف'; + @override String get updateTimerInterval => 'الفاصل الزمني للتحديث'; + @override String get updateTimerIntervalTips => 'الحد الأدنى: 5 م'; + @override String get profileLinkContent => 'رابط/محتوى الملف الشخصي'; + @override String get profileLinkContentHit => 'ارتباط ملف التعريف/المحتوى [مطلوب] (دعم الدعم ، V2Ray (مدعوم الدفعة) ، خبأ ، karing ، sing-box ، shadowsocks ، روابط الملف الشخصي الفرعي)'; + @override String get subscriptionCannotEmpty => 'لا يمكن أن يكون رابط الملف الشخصي فارغًا'; + @override String get configExist => 'الملف الشخصي موجود بالفعل ، من فضلك لا تضيفه مرارًا وتكرارًا'; + @override String get invalidUrl => 'رابط الملف الطويل جدًا'; + @override String addFailedFormatException({required Object p}) => 'التنسيق خاطئ ، يرجى تصحيحه وإضافته مرة أخرى:${p}'; + @override String addFailedThenDownloadAndImport({required Object p}) => 'فشلت إضافة: ${p}، يرجى محاولة تعديل [UserAgent] والمحاولة مرة أخرى، أو استخدم المتصفح الخاص بالجهاز لفتح رابط التكوين واستيراد ملف التكوين الذي تم تنزيله بواسطة المتصفح إلى هذا التطبيق'; + @override String addFailedHandshakeException({required Object p}) => 'فشلت إضافة: ${p}، يرجى فتح الوكيل أو تعديل عقدة الوكيل الحالية والمحاولة مرة أخرى'; +} + +// Path: AddProfileByScanQrcodeScanScreen +class _TranslationsAddProfileByScanQrcodeScanScreenAr implements TranslationsAddProfileByScanQrcodeScanScreenEn { + _TranslationsAddProfileByScanQrcodeScanScreenAr._(this._root); + + final TranslationsAr _root; // ignore: unused_field + + // Translations + @override String get copy => 'Copy Link'; + @override String get open => 'Open Link'; + @override String get requestCameraPermission => 'يرجى تمكين إذن الكاميرا'; + @override String get requestScreenAccess => 'يرجى الانتقال إلى إعدادات النظام - الخصوصية والأمان - تسجيل الشاشة لإضافة أذونات لهذا التطبيق'; + @override String get screenshot => 'لقطة شاشة'; + @override String get scanFromImage => 'مسح من الصورة'; + @override String get scanNoResult => 'فشل في تحليل الصورة ، يرجى التأكد من أن لقطة الشاشة هي رمز QR صالح'; + @override String get scanEmptyResult => 'نتيجة الفحص فارغة'; + @override String scanException({required Object p}) => 'فشل في تحليل الصورة ، يرجى التأكد من أن لقطة الشاشة هي رمز QR صالح: ${p}'; +} + +// Path: BackupAndSyncLanSyncScreen +class _TranslationsBackupAndSyncLanSyncScreenAr implements TranslationsBackupAndSyncLanSyncScreenEn { + _TranslationsBackupAndSyncLanSyncScreenAr._(this._root); + + final TranslationsAr _root; // ignore: unused_field + + // Translations + @override String get title => 'LAN SYNC'; + @override String get lanSyncNotQuitTips => 'لا تخرج من هذه الواجهة قبل اكتمال التزامن'; +} + +// Path: BackupAndSyncWebdavScreen +class _TranslationsBackupAndSyncWebdavScreenAr implements TranslationsBackupAndSyncWebdavScreenEn { + _TranslationsBackupAndSyncWebdavScreenAr._(this._root); + + final TranslationsAr _root; // ignore: unused_field + + // Translations + @override String get webdavServerUrl => 'عنوان URL الخادم'; + @override String get webdavRequired => 'لايمكن ان يكون فارغا'; + @override String get webdavLoginFailed => 'فشل تسجيل الدخول:'; + @override String get webdavListFailed => 'فشل في الحصول على قائمة الملفات:'; +} + +// Path: DiversionGroupCustomEditScreen +class _TranslationsDiversionGroupCustomEditScreenAr implements TranslationsDiversionGroupCustomEditScreenEn { + _TranslationsDiversionGroupCustomEditScreenAr._(this._root); + + final TranslationsAr _root; // ignore: unused_field + + // Translations + @override String invalidDomain({required Object p}) => 'غير صالح [Domain]:${p}'; + @override String invalidIpCidr({required Object p}) => 'غير صالح [IP Cidr]:${p}'; + @override String invalidPort({required Object p}) => 'غير صالح [Port]:${p}'; + @override String invalidRuleSet({required Object p}) => 'غير صالح [Rule Set]:${p}, يجب أن يكون عنوان URL عنوان URL HTTPS صالحًا وملفًا ثنائيًا مع ملحق الملف .SRS'; + @override String invalidRuleSetBuildIn({required Object p}) => 'غير صالح [Rule Set(build-in)]:${p} غير صالحة، التنسيق هو geosite:xxx أو geoip:xxx أو acl:xxx، ويجب أن يكون xxx اسم قاعدة صالحًا'; + @override String get setDiversionRule => 'نصيحة: بعد الحفظ، يرجى الانتقال إلى [قواعد التحويل] لتعيين القواعد ذات الصلة، وإلا فلن تصبح سارية المفعول.'; +} + +// Path: DiversionRuleDetectScreen +class _TranslationsDiversionRuleDetectScreenAr implements TranslationsDiversionRuleDetectScreenEn { + _TranslationsDiversionRuleDetectScreenAr._(this._root); + + final TranslationsAr _root; // ignore: unused_field + + // Translations + @override String get title => 'قاعدة التحويل اكتشف'; + @override String get detect => 'يكشف'; + @override String get rule => 'قاعدة:'; + @override String get outbound => 'مخدم بروكسي:'; +} + +// Path: DiversionRulesScreen +class _TranslationsDiversionRulesScreenAr implements TranslationsDiversionRulesScreenEn { + _TranslationsDiversionRulesScreenAr._(this._root); + + final TranslationsAr _root; // ignore: unused_field + + // Translations + @override String get diversionRulesMatchTips => 'نصيحة: حاول مطابقة القواعد من الأعلى إلى الأسفل، إذا لم تتم مطابقة أي قاعدة، استخدم [نهائي]'; +} + +// Path: DnsSettingsScreen +class _TranslationsDnsSettingsScreenAr implements TranslationsDnsSettingsScreenEn { + _TranslationsDnsSettingsScreenAr._(this._root); + + final TranslationsAr _root; // ignore: unused_field + + // Translations + @override String get ispCanNotEmpty => 'لا يمكن أن يكون ISP فارغًا'; + @override String get urlCanNotEmpty => 'لا يمكن أن يكون عنوان URL فارغًا'; + @override String error({required Object p}) => 'نوع غير مدعوم:${p}'; + @override String get dnsDesc => 'العمود الأول من بيانات التأخير هو تأخير استعلام الاتصال المباشر;\nالعمود الثاني: شغله [[حركة الوكيل]حل DNS من خلال خادم الوكيل]: بيانات التأخير هي تأخير الاستعلام الذي تم إعادة توجيهه من خلال خادم الوكيل الحالي; إذا [[حركة الوكيل]حل DNS من خلال خادم الوكيل]: بيانات التأخير هي تأخير استعلام الاتصال المباشر'; +} + +// Path: FeedbackScreen +class _TranslationsFeedbackScreenAr implements TranslationsFeedbackScreenEn { + _TranslationsFeedbackScreenAr._(this._root); + + final TranslationsAr _root; // ignore: unused_field + + // Translations + @override String get content => 'محتوى ردود الفعل'; + @override String get contentHit => 'مطلوب ، ما يصل إلى 500 حرف'; + @override String get contentCannotEmpty => 'لا يمكن أن يكون محتوى التعليقات فارغًا'; +} + +// Path: FileContentViewerScreen +class _TranslationsFileContentViewerScreenAr implements TranslationsFileContentViewerScreenEn { + _TranslationsFileContentViewerScreenAr._(this._root); + + final TranslationsAr _root; // ignore: unused_field + + // Translations + @override String get title => 'ملف محتوى الملف'; + @override String get chooseFile => 'حدد الملف'; + @override String get clearFileContent => 'هل أنت متأكد من مسح محتوى الملف؟'; + @override String get clearFileContentTips => 'هل أنت متأكد من مسح محتوى ملف الملف الشخصي؟قد يتسبب تطهير ملف الملف الشخصي في فقدان البيانات أو وظائف التطبيق غير الطبيعية ، يرجى العمل بحذر'; +} + +// Path: HomeScreen +class _TranslationsHomeScreenAr implements TranslationsHomeScreenEn { + _TranslationsHomeScreenAr._(this._root); + + final TranslationsAr _root; // ignore: unused_field + + // Translations + @override String get toSelectServer => 'الرجاء تحديد خادم'; + @override String get invalidServer => 'غير صالح ، الرجاء اختيار مرة أخرى'; + @override String get disabledServer => 'معطل ، الرجاء اختيار مرة أخرى'; + @override String get expiredServer => 'لا يوجد خادم متاح: قد يكون التكوين قديمًا أو معطلاً'; + @override String systemProxyTips({required Object sp, required Object hp}) => 'جوارب:${sp},http(s):${hp}'; + @override String get trafficTotal => 'إجمالي حركة المرور'; + @override String get trafficProxy => 'وكيل حركة المرور'; + @override String get myLinkEmpty => 'الرجاء الإعداد [الاختصار وصلة] قبل استخدامه'; + @override String get deviceNoSpace => 'مساحة غير كافيه في القرص'; + @override String tooMuchServers({required Object p, required Object p1}) => 'يوجد عدد كبير جدًا من الخوادم الوكيلة [${p}>${p1}]، وقد لا يكون الاتصال ممكنًا بسبب قيود ذاكرة النظام.'; +} + +// Path: LaunchFailedScreen +class _TranslationsLaunchFailedScreenAr implements TranslationsLaunchFailedScreenEn { + _TranslationsLaunchFailedScreenAr._(this._root); + + final TranslationsAr _root; // ignore: unused_field + + // Translations + @override String get invalidProcess => 'فشل التطبيق في البدء [اسم عملية غير صالح] ، يرجى إعادة تثبيت التطبيق إلى دليل منفصل'; + @override String get invalidProfile => 'فشل التطبيق في البدء [فشل في الوصول إلى الملف الشخصي] ، يرجى إعادة تثبيت التطبيق'; + @override String get invalidVersion => 'فشل التطبيق في بدء [إصدار غير صالح] ، يرجى إعادة تثبيت التطبيق'; + @override String get systemVersionLow => 'فشل بدء تشغيل التطبيق [إصدار النظام منخفض جدًا]'; + @override String get invalidInstallPath => 'مسار التثبيت غير صالح ، يرجى إعادة تثبيته إلى مسار صالح'; +} + +// Path: MyProfilesEditScreen +class _TranslationsMyProfilesEditScreenAr implements TranslationsMyProfilesEditScreenEn { + _TranslationsMyProfilesEditScreenAr._(this._root); + + final TranslationsAr _root; // ignore: unused_field + + // Translations + @override String get title => 'تحرير الملف الشخصي'; + @override String get urlExist => 'عنوان URL موجود بالفعل ، يرجى استخدام عنوان URL آخر'; + @override String get updateTimerInterval => 'الفاصل الزمني للتحديث'; + @override String get updateTimerIntervalTips => 'الحد الأدنى: 5 م'; + @override String get reloadAfterProfileUpdate => 'إعادة التحميل بعد تحديث الملف الشخصي'; + @override String get testLatencyAfterProfileUpdate => 'ابدأ اختبارات الكمون بعد التحديث تلقائيًا'; + @override String get testLatencyAfterProfileUpdateTips => 'يجب توصيل VPN ، وتمكين [إعادة التحميل بعد تحديث الملف الشخصي]'; + @override String get testLatencyAutoRemove => 'إزالة الخوادم التي تفشل تلقائيا اختبارات الكمون'; + @override String get testLatencyAutoRemoveTips => 'جرب ما يصل إلى 3 مرات'; +} + +// Path: MyProfilesMergeScreen +class _TranslationsMyProfilesMergeScreenAr implements TranslationsMyProfilesMergeScreenEn { + _TranslationsMyProfilesMergeScreenAr._(this._root); + + final TranslationsAr _root; // ignore: unused_field + + // Translations + @override String get profilesMerge => 'دمج الملامح'; + @override String get profilesMergeTarget => 'ملف تعريف الهدف'; + @override String get profilesMergeSource => 'ملفات تعريف المصدر'; + @override String get profilesMergeTips => 'نصيحة: سيتم تجاهل تحويل ملفات تعريف المصدر'; +} + +// Path: MyProfilesScreen +class _TranslationsMyProfilesScreenAr implements TranslationsMyProfilesScreenEn { + _TranslationsMyProfilesScreenAr._(this._root); + + final TranslationsAr _root; // ignore: unused_field + + // Translations + @override String get title => 'مظهر'; + @override String get atLeastOneEnable => 'لا يمكن تعطيله ، يرجى الاحتفاظ بملف تعريف واحد على الأقل'; +} + +// Path: NetCheckScreen +class _TranslationsNetCheckScreenAr implements TranslationsNetCheckScreenEn { + _TranslationsNetCheckScreenAr._(this._root); + + final TranslationsAr _root; // ignore: unused_field + + // Translations + @override String get title => 'فحص صافي'; + @override String get warn => 'ملاحظة: نظرًا لتأثير بيئة الشبكة وقواعد التحويل ، فإن نتائج الاختبار ليست مكافئة تمامًا للنتائج الفعلية.'; + @override String get check => 'يفحص'; + @override String get invalidDomain => 'اسم النطاق غير صالح'; + @override String get connectivity => 'اتصال الشبكة'; + @override String connectivityTestIpv4AllFailed({required Object p}) => 'اختبار اتصال IPv4[${p}] كل شيء فشل'; + @override String get connectivityTestIpv4Ok => 'Ipv4 نجح الاتصال'; + @override String connectivityTestIpv6AllFailed({required Object p}) => 'Ipv6 اختبار الاتصال [${p}] كل شيء فشل ، قد لا تدعم شبكتك IPv6'; + @override String get connectivityTestIpv6Ok => 'نجح اتصال IPv6'; + @override String get connectivityTestOk => 'الشبكة متصلة بالإنترنت'; + @override String get connectivityTestFailed => 'الشبكة ليست متصلة بعد بالإنترنت'; + @override String get remoteRulesetsDownloadOk => 'تم تنزيل كل شيء بنجاح'; + @override String get remoteRulesetsDownloadNotOk => 'التحميل أو فشل'; + @override String get outbound => 'مخدم بروكسي'; + @override String outboundOk({required Object p}) => '[${p}] نجح الاتصال '; + @override String outboundFailed({required Object p1, required Object p2}) => '[${p1}] فشل الاتصال\nError:[${p2}]'; + @override String get dnsServer => 'DNS الخادم'; + @override String dnsOk({required Object p1, required Object p2, required Object p3, required Object p4}) => '[${p1}]نجح استعلام DNS\nDNS قاعدة:[${p2}]\n وقت الإستجابة:[${p3} ms]\nAعنوان[${p4}]'; + @override String dnsFailed({required Object p1, required Object p2, required Object p3}) => '[${p1}]نجح استعلام DNS\n nDNS قاعدة:[${p2}]\nخطأ:[${p3}]'; + @override String get host => 'اتصال HTTP'; + @override String hostConnection({required Object p1, required Object p2, required Object p3}) => '[${p1}]\nقاعدة التحويل:[${p2}]\nمخدم بروكسي:[${p3}]'; + @override String get hostConnectionOk => 'نجح الاتصال'; + @override String hostConnectionFailed({required Object p}) => 'فشل الاتصال:[${p}]'; +} + +// Path: NetConnectionsFilterScreen +class _TranslationsNetConnectionsFilterScreenAr implements TranslationsNetConnectionsFilterScreenEn { + _TranslationsNetConnectionsFilterScreenAr._(this._root); + + final TranslationsAr _root; // ignore: unused_field + + // Translations + @override String get title => 'تصفية الاتصالات'; + @override String get hostIp => 'المجال/IP'; + @override String get app => 'برنامج'; + @override String get rule => 'قاعدة'; + @override String get chain => 'خارج'; +} + +// Path: NetConnectionsScreen +class _TranslationsNetConnectionsScreenAr implements TranslationsNetConnectionsScreenEn { + _TranslationsNetConnectionsScreenAr._(this._root); + + final TranslationsAr _root; // ignore: unused_field + + // Translations + @override String get title => 'روابط'; + @override String get copyAsCSV => 'نسخ إلى تنسيق CSV'; + @override String get selectType => 'حدد نوع التحويل'; +} + +// Path: PerAppAndroidScreen +class _TranslationsPerAppAndroidScreenAr implements TranslationsPerAppAndroidScreenEn { + _TranslationsPerAppAndroidScreenAr._(this._root); + + final TranslationsAr _root; // ignore: unused_field + + // Translations + @override String get title => 'لكل وكيل تطبيق'; + @override String get whiteListMode => 'وضع القائمة البيضاء'; + @override String get whiteListModeTip => 'عند التمكين: فقط التطبيقات التي تم فحصها هي وكلاء ؛عندما لا يتم تمكينها: فقط التطبيقات التي لم يتم فحصها هي وكلاء'; + @override String get hideSystemApp => 'إخفاء تطبيقات النظام'; + @override String get hideAppIcon => 'إخفاء أيقونة التطبيق'; + @override String get enableAppQueryPermission => 'قم بتشغيل الإذن [استعلام قائمة التطبيقات]'; +} + +// Path: QrcodeScreen +class _TranslationsQrcodeScreenAr implements TranslationsQrcodeScreenEn { + _TranslationsQrcodeScreenAr._(this._root); + + final TranslationsAr _root; // ignore: unused_field + + // Translations + @override String get tooLong => 'النص طويل جدًا لعرضه'; + @override String get copy => 'نسخ الوصلة'; + @override String get open => 'افتح الرابط'; + @override String get share => 'شارك الرابط'; + @override String get shareImage => 'شارك رمز الاستجابة السريعة'; +} + +// Path: RegionSettingsScreen +class _TranslationsRegionSettingsScreenAr implements TranslationsRegionSettingsScreenEn { + _TranslationsRegionSettingsScreenAr._(this._root); + + final TranslationsAr _root; // ignore: unused_field + + // Translations + @override String get title => 'الدولة او المنطقة'; + @override String get Regions => ' نصيحة: يرجى تعيين بلدك أو منطقتك الحالية بشكل صحيح ، وإلا فقد يتسبب في مشاكل في تحويل الشبكة'; +} + +// Path: ServerSelectScreen +class _TranslationsServerSelectScreenAr implements TranslationsServerSelectScreenEn { + _TranslationsServerSelectScreenAr._(this._root); + + final TranslationsAr _root; // ignore: unused_field + + // Translations + @override String get title => 'حدد الخادم'; + @override String get autoSelectServer => 'تلقائي حدد الخادم بأقل زمن انتقال'; + @override String get recentUse => 'مستخدم حديثا'; + @override String get myFav => 'المفضل لدي'; + @override String selectLocal({required Object p}) => 'الخادم المحدد هو عنوان محلي وقد لا يعمل بشكل صحيح:${p}'; + @override String get selectRequireEnableIPv6 => 'الخادم المحدد هو عنوان IPv6 ويتطلب [تمكين IPv6]'; + @override String get selectDisabled => 'تم تعطيل هذا الخادم'; + @override String get error404 => 'واجه اكتشاف الكمون خطأ ، يرجى التحقق مما إذا كان هناك تكوين مع نفس المحتوى'; +} + +// Path: SettingsScreen +class _TranslationsSettingsScreenAr implements TranslationsSettingsScreenEn { + _TranslationsSettingsScreenAr._(this._root); + + final TranslationsAr _root; // ignore: unused_field + + // Translations + @override String ispFaq({required Object p}) => 'أسئلة مكررة[${p}]'; + @override String cleanISP({required Object p}) => 'ISP واضح[${p}]'; + @override String get openISP => 'فتح ISP رابط'; + @override String get cleanISPNoParam => 'مسح معلومات مزود خدمة الإنترنت '; + @override String get getTranffic => 'احصل على حركة المرور'; + @override String get tutorial => 'درس تعليمي'; + @override String get commonlyUsedRulesets => 'مجموعات القواعد شائعة الاستخدام'; + @override String get howToRemoveAds => 'كيفية إزالة الإعلانات'; + @override String get htmlBoard => 'لوحة على الانترنت'; + @override String get dnsLeakDetection => 'كشف تسرب DNS'; + @override String get speedTest => 'اختبار السرعة'; + @override String get downloadProfilePreferProxy => 'تفضل الوكيل لتنزيل الملف الشخصي'; + @override String get downloadProfilePreferProxyTips => 'إذا كان متصلاً حاليًا ، فسيتم تنزيل الملف الشخصي من خلال الوكيل المتصالح أولاً'; + @override String get rulesetDirectDownlad => 'مجموعة القواعد تحميل مباشر'; + @override String get hideUnusedDiversionGroup => 'إخفاء مجموعات التحويل غير المستخدمة'; + @override String get disableISPDiversionGroup => 'تعطيل قواعد تحويل ISP'; + @override String get portSetting => 'ميناء'; + @override String get portSettingRule => 'القاعدة القائمة'; + @override String get portSettingDirectAll => 'توجيه كل شيء'; + @override String get portSettingProxyAll => 'وكيل الكل'; + @override String get portSettingControl => 'السيطرة والمزامنة'; + @override String get portSettingCluster => 'خدمة الكتلة'; + @override String get modifyPort => 'تعديل المنفذ'; + @override String get modifyPortOccupied => 'المنفذ مشغول، يرجى استخدام منفذ آخر'; + @override String get ipStrategyTips => 'قبل التمكين ، يرجى تأكيد أن شبكتك تدعم IPv6 ، وإلا لا يمكن الوصول إلى بعض حركة المرور بشكل طبيعي.'; + @override String get tunAppendHttpProxy => 'إلحاق وكيل HTTP إلى VPN'; + @override String get tunAppendHttpProxyTips => 'ستجاوز بعض التطبيقات جهاز NIC الظاهري والاتصال مباشرة بوكيل HTTP'; + @override String get tlsInsecureEnable => 'تخطي التحقق من الشهادة'; + @override String get tlsFragmentEnable => 'تمكين تجزئة TLS'; + @override String get tlsFragmentSize => 'حجم شريحة TLS'; + @override String get tlsFragmentSleep => 'TLS النوم المجزأ'; + @override String get tlsMixedCaseSNIEnable => 'تمكين TLS الهجين SNI'; + @override String get tlsPaddingEnable => 'تمكين الحشو TLS'; + @override String get tlsPaddingSize => 'حجم الحشو TLS'; + @override String get dnsEnableRule => 'تمكين قواعد تحويل DNS'; + @override String get dnsEnableFakeIp => 'تمكين وهمية'; + @override String get dnsEnableClientSubnet => 'تمكين ECS'; + @override String get dnsEnableProxyResolveByProxy => '[حركة الوكيل] حل DNS من خلال خادم الوكيل'; + @override String get dnsEnableFinalResolveByProxy => '[نهائي] حل DNS من خلال خادم الوكيل'; + @override String get dnsTestDomain => 'مجال الاختبار'; + @override String get dnsTestDomainInvalid => 'مجال غير صالح'; + @override String get dnsTypeOutbound => 'مخدم بروكسي'; + @override String get dnsTypeDirect => 'سير مستقيم'; + @override String get dnsTypeProxy => 'حركة الوكيل'; + @override String get dnsTypeResolver => 'خادم DNS'; + @override String get dnsEnableRuleTips => 'بعد التمكين ، سيختار اسم المجال خادم DNS المقابل للدقة وفقًا لقواعد التحويل'; + @override String get dnsEnableFakeIpTips => 'بعد تمكين FakeIP، إذا تم قطع اتصال VPN، فقد يلزم إعادة تشغيل التطبيق الخاص بك؛ يجب تشغيل هذه الوظيفة [وضع TUN]'; + @override String get dnsTypeOutboundTips => 'دقة اسم المجال لخادم الوكيل'; + @override String get dnsTypeDirectTips => 'حل اسم المجال لحركة المرور المباشرة'; + @override String get dnsTypeProxyTips => 'حل اسم المجال لحركة المرور الوكيل'; + @override String get dnsTypeResolverTips => 'دقة اسم المجال لخادم DNS الآخر'; + @override String get dnsTypeFinalTips => 'حل اسم المجال لحركة المرور الأخرى'; + @override String get dnsAutoSetServer => 'إعداد الخادم تلقائيا'; + @override String get dnsResetServer => 'إعادة تعيين الخادم'; + @override String get inboundDomainResolve => 'حل أسماء النطاقات الواردة'; + @override String get privateDirect => 'اتصال مباشر بالشبكة الخاصة'; + @override String inboundDomainResolveTips({required Object p}) => 'تحتاج بعض أسماء النطاقات التي لا تحتوي على قواعد تحويل تم تكوينها إلى حلها قبل أن تتمكن من الوصول إلى قواعد التحويل المستندة إلى IP؛ وتؤثر هذه الميزة على الطلبات الواردة إلى منفذ الوكيل [${p}]'; + @override String get useRomoteRes => 'استخدم الموارد البعيدة'; + @override String get autoSelect => 'اختيار آلي'; + @override String get autoSelectServerIgnorePerProxyServer => 'تجاهل الخادم الوكيل [الوكيل الأمامي].'; + @override String get autoSelectServerInterval => 'فاصل الشيكات الكمون'; + @override String get autoSelectServerReTestIfNetworkUpdate => 'إعادة اكتشاف متى تتغير الشبكة'; + @override String get autoSelectServerUpdateCurrentServerAfterManualUrltest => 'قم بتحديث الخادم الحالي بعد الكشف اليدوي عن التأخير'; + @override String get autoSelectServerIntervalTips => 'كلما كان الفاصل الزمني لاكتشاف التأخير أقصر، كلما تم تحديث بيانات تأخير الخادم في الوقت المناسب، ولكنها ستشغل المزيد من الموارد وتستهلك الكهرباء بشكل أسرع'; + @override String get autoSelectServerFavFirst => 'PRI-Use [My Favs]'; + @override String get autoSelectServerFavFirstTips => 'إذا لم تكن قائمة [Favs] فارغة ، فاستخدم الخوادم في [Favs]'; + @override String get autoSelectServerFilter => 'تصفية خوادم غير صالحة'; + @override String autoSelectServerFilterTips({required Object p}) => 'سيتم تصفية حالات فشل الكشف عن تأخير الخادم؛ إذا لم يكن هناك خادم متاح بعد التصفية، فسيتم استخدام الخوادم [${p}] الأولى بدلاً من ذلك.'; + @override String get autoSelectServerLimitedNum => 'الحد الأقصى لعدد الخوادم'; + @override String get autoSelectServerLimitedNumTips => 'سيتم تصفية الخوادم التي تتجاوز هذا الرقم'; + @override String get numInvalid => 'رقم غير صالح'; + @override String get hideInvalidServer => 'إخفاء الخوادم غير الصالحة'; + @override String get sortServer => 'خوادم الفرز'; + @override String get sortServerTips => 'فرز حسب الكمون من منخفض إلى مرتفع'; + @override String get selectServerHideRecommand => 'إخفاء [يوصي]'; + @override String get selectServerHideRecent => 'إخفاء [المستخدمة مؤخرًا]'; + @override String get selectServerHideFav => 'إخفاء [المفضلة لدي]'; + @override String get homeScreen => 'الشاشة الرئيسية'; + @override String get theme => 'Tالهيم'; + @override String get myLink => 'ارتباط اختصار'; + @override String get myLinkInvalid => 'URL غير صالح'; + @override String get autoConnectAfterLaunch => 'اتصال السيارات بعد الإطلاق'; + @override String get hideAfterLaunch => 'إخفاء النافذة بعد بدء التشغيل'; + @override String get autoSetSystemProxy => 'وكيل نظام تعيين تلقائي عند الاتصال'; + @override String get disconnectWhenQuit => 'افصل عندما يخرج التطبيق'; + @override String get allowBypass => 'السماح للتطبيقات بتجاوز VPN'; + @override String get importSuccess => 'استيراد نجاح '; + @override String get rewriteConfirm => 'سيقوم هذا الملف بكتابة التكوين المحلي الحالي.هل تريد الاستمرار؟'; + @override String get networkShare => 'مشاركة الشبكة'; + @override String get frontProxy => 'الوكيل الأمامي'; + @override String frontProxyTips({required Object p}) => 'البيانات->الخادم الوكيل الأمامي [خوادم بروكسي أمامية متعددة: من الأعلى إلى الأسفل]->الخادم الوكيل [${p}]->الخادم الهدف'; + @override String get allowOtherHostsConnect => 'اسمح للآخرين بالاتصال'; + @override String allowOtherHostsConnectTips({required Object sp, required Object hp}) => 'socks:${sp},http(s):${hp}'; + @override String get tunAutoRoute => 'Auto Route'; + @override String get tunStrictRoute => 'Strict Route'; + @override String get tunStrictRouteTips => 'إذا لم يتمكن الآخرون من الوصول إلى هذا الجهاز بعد تشغيل المشاركة، فيرجى محاولة إيقاف تشغيل هذا المفتاح.'; + @override String get enableCluster => 'تمكين مجموعة الوكيل الجوارب/HTTP'; + @override String get clusterAllowOtherHostsConnect => 'السماح للآخرين بالاتصال بـ CLUSTER'; + @override String clusterAllowOtherHostsConnectTips({required Object ip, required Object port}) => 'http://${ip}:${port}/get_proxies'; + @override String get clusterAuth => 'مصادقة مجموعة الوكيل'; + @override String get tunMode => 'نفق وضع'; + @override String get tunModeTips => 'سيتولى وضع TUN كل حركة مرور النظام [في هذا الوضع ، يمكنك ترك وكيل النظام غير مدقلة]'; + @override String get tunModeRunAsAdmin => 'يتطلب وضع TUN أذونات مسؤول النظام ، يرجى إعادة تشغيل التطبيق كمسؤول'; + @override String get tunStack => 'Stack'; + @override String get launchAtStartup => 'إطلاق عند بدء التشغيل'; + @override String get quitWhenSwitchSystemUser => 'خروج تطبيق عند تبديل مستخدمي النظام'; + @override String get handleScheme => 'مكالمة مخطط النظام'; + @override String get portableMode => 'الوضع المحمول'; + @override String get portableModeDisableTips => 'إذا كنت بحاجة إلى الخروج من الوضع المحمول، فيرجى الخروج من [karing] وحذف المجلد [profiles] يدويًا في نفس الدليل مثل [karing.exe]'; + @override String get handleKaringScheme => 'مقبض karing:// Call'; + @override String get handleClashScheme => 'مقبض clash:// Call'; + @override String get handleSingboxScheme => 'مقبض sing-box:// يتصل'; + @override String get alwayOnVPN => 'اتصال مفتوح دائمًا'; + @override String get removeSystemVPNConfig => 'حذف تكوين VPN النظام'; + @override String get timeConnectOrDisconnect => 'المقرر يتصل/قطع الاتصال'; + @override String get timeConnectOrDisconnectTips => 'يجب أن يكون VPN متصلاً ليصبح مفيدًا ؛بعد تشغيله ، سيتم تعطيل [النوم التلقائي]'; + @override String timeConnectAndDisconnectInterval({required Object p}) => 'ال cاتصاللا يمكن أن يكون فاصل الانفصال أقل من ${p} دقائق'; + @override String get disableFontScaler => 'تعطيل تحجيم الخط(إعادة التشغيل يسري)'; + @override String get autoOrientation => 'اتبع دوران الشاشة'; + @override String get restartTakesEffect => 'إعادة التشغيل يسري'; + @override String get resetSettings => 'اعادة الضبط'; + @override String get cleanCache => 'مسح ذاكرة التخزين المؤقت'; + @override String get cleanCacheDone => 'اكتملت عملية التنظيف'; + @override String get appleTestFlight => 'Apple Testflight'; + @override String get appleAppStore => 'متجر تطبيقات Apple'; + @override String hasNewVersion({required Object p}) => 'تحديث الإصدار ${p}'; + @override String get follow => 'تابعنا'; + @override String get contactUs => 'اتصل بنا'; + @override String get rateInApp => 'قيمنا'; + @override String get rateInAppStore => 'قيمنا في متجر التطبيقات'; +} + +// Path: SpeedTestSettingsScreen +class _TranslationsSpeedTestSettingsScreenAr implements TranslationsSpeedTestSettingsScreenEn { + _TranslationsSpeedTestSettingsScreenAr._(this._root); + + final TranslationsAr _root; // ignore: unused_field + + // Translations + @override String get title => 'URL اختبار السرعة'; +} + +// Path: TextToQrCodeScreen +class _TranslationsTextToQrCodeScreenAr implements TranslationsTextToQrCodeScreenEn { + _TranslationsTextToQrCodeScreenAr._(this._root); + + final TranslationsAr _root; // ignore: unused_field + + // Translations + @override String get title => 'رسالة نصية إلى رمز الاستجابة السريعة'; + @override String get convert => 'يتحول'; +} + +// Path: UserAgreementScreen +class _TranslationsUserAgreementScreenAr implements TranslationsUserAgreementScreenEn { + _TranslationsUserAgreementScreenAr._(this._root); + + final TranslationsAr _root; // ignore: unused_field + + // Translations + @override String get privacyFirst => 'خصوصيتك تأتي أولا'; + @override String get agreeAndContinue => 'قبول ومتابعة'; +} + +// Path: VersionUpdateScreen +class _TranslationsVersionUpdateScreenAr implements TranslationsVersionUpdateScreenEn { + _TranslationsVersionUpdateScreenAr._(this._root); + + final TranslationsAr _root; // ignore: unused_field + + // Translations + @override String versionReady({required Object p}) => 'الإصدار الجديد [${p}] جاهز'; + @override String get update => 'أعد التشغيل للتحديث'; + @override String get cancel => 'ليس الآن'; +} + +// Path: CommonWidget +class _TranslationsCommonWidgetAr implements TranslationsCommonWidgetEn { + _TranslationsCommonWidgetAr._(this._root); + + final TranslationsAr _root; // ignore: unused_field + + // Translations + @override String get diableAlwayOnVPN => 'إذا تم تشغيل [Always on VPN]، فيرجى إيقاف تشغيل [Always on VPN] ومحاولة الاتصال مرة أخرى.'; + @override String get resetPort => 'الرجاء تغيير المنفذ إلى منفذ آخر متاح أو إغلاق التطبيق الذي يشغل المنفذ.'; +} + +// Path: ServerManager +class _TranslationsServerManagerAr implements TranslationsServerManagerEn { + _TranslationsServerManagerAr._(this._root); + + final TranslationsAr _root; // ignore: unused_field + + // Translations + @override String get noServerAvaliable => 'لا يوجد خادم متاح، يرجى التأكد من صلاحية رابط التكوين أو ملف التكوين؛ وإذا كان التكوين الخاص بك يأتي من GitHub، فيرجى الحصول على عنوان الرابط من الزر [Raw] الموجود في الصفحة'; + @override String get filePathCannotEmpty => 'لا يمكن أن يكون مسار الملف فارغًا'; + @override String fileNotExist({required Object p}) => 'الملف غير موجود: ${p}'; + @override String get urlCannotEmpty => 'لا يمكن أن يكون الرابط فارغًا'; + @override String get invalidUrl => 'رابط ملف تعريف غير صالح'; + @override String get parseFailed => 'فشل تحليل الملف الشخصي'; +} + +// Path: main +class _TranslationsMainAr implements TranslationsMainEn { + _TranslationsMainAr._(this._root); + + final TranslationsAr _root; // ignore: unused_field + + // Translations + @override late final _TranslationsMainTrayAr tray = _TranslationsMainTrayAr._(_root); +} + +// Path: main.tray +class _TranslationsMainTrayAr implements TranslationsMainTrayEn { + _TranslationsMainTrayAr._(this._root); + + final TranslationsAr _root; // ignore: unused_field + + // Translations + @override String get menuOpen => ' يفتح '; + @override String get menuExit => ' مخرج '; +} + +/// Flat map(s) containing all translations. +/// Only for edge cases! For simple maps, use the map function of this library. +extension on TranslationsAr { + dynamic _flatMapFunction(String path) { + switch (path) { + case 'AboutScreen.installRefer': return 'تثبيت الرجوع'; + case 'AboutScreen.versionChannel': return 'تحديث القنوات تلقائيا'; + case 'AboutScreen.disableUAReport': return 'قم بإيقاف تشغيل تقرير بيانات الإجراء'; + case 'AboutScreen.disableUAReportTip': return 'تساعدنا تقارير البيانات السلوكية على تحسين تجربة المنتج؛ ستقوم الإصدارات الأقل من الإصدار الرئيسي بإيقاف تشغيل جميع تقارير البيانات تلقائيًا (باستثناء [تنشيط التطبيق])'; + case 'AboutScreen.devOptions': return 'خيارات للمطور'; + case 'AboutScreen.enableDebugLog': return 'تمكين سجل التصحيح'; + case 'AboutScreen.viewFilsContent': return 'عرض الملفات'; + case 'AboutScreen.enablePprof': return 'يُمكَِن pprof'; + case 'AboutScreen.pprofPanel': return 'pprof لوحة'; + case 'AboutScreen.openDir': return 'فتح دليل الملف'; + case 'AboutScreen.useOriginalSBProfile': return 'استخدم تكوين صندوق الغناء الأصلي'; + case 'AddProfileByImportFromFileScreen.title': return 'استيراد ملف الملف الشخصي'; + case 'AddProfileByImportFromFileScreen.chooseFile': return 'حدد الملف'; + case 'AddProfileByImportFromFileScreen.configExist': return 'الملف الشخصي موجود بالفعل ، من فضلك لا تضيفه مرارًا وتكرارًا'; + case 'AddProfileByLinkOrContentScreen.title': return 'إضافة رابط ملف التعريف'; + case 'AddProfileByLinkOrContentScreen.updateTimerInterval': return 'الفاصل الزمني للتحديث'; + case 'AddProfileByLinkOrContentScreen.updateTimerIntervalTips': return 'الحد الأدنى: 5 م'; + case 'AddProfileByLinkOrContentScreen.profileLinkContent': return 'رابط/محتوى الملف الشخصي'; + case 'AddProfileByLinkOrContentScreen.profileLinkContentHit': return 'ارتباط ملف التعريف/المحتوى [مطلوب] (دعم الدعم ، V2Ray (مدعوم الدفعة) ، خبأ ، karing ، sing-box ، shadowsocks ، روابط الملف الشخصي الفرعي)'; + case 'AddProfileByLinkOrContentScreen.subscriptionCannotEmpty': return 'لا يمكن أن يكون رابط الملف الشخصي فارغًا'; + case 'AddProfileByLinkOrContentScreen.configExist': return 'الملف الشخصي موجود بالفعل ، من فضلك لا تضيفه مرارًا وتكرارًا'; + case 'AddProfileByLinkOrContentScreen.invalidUrl': return 'رابط الملف الطويل جدًا'; + case 'AddProfileByLinkOrContentScreen.addFailedFormatException': return ({required Object p}) => 'التنسيق خاطئ ، يرجى تصحيحه وإضافته مرة أخرى:${p}'; + case 'AddProfileByLinkOrContentScreen.addFailedThenDownloadAndImport': return ({required Object p}) => 'فشلت إضافة: ${p}، يرجى محاولة تعديل [UserAgent] والمحاولة مرة أخرى، أو استخدم المتصفح الخاص بالجهاز لفتح رابط التكوين واستيراد ملف التكوين الذي تم تنزيله بواسطة المتصفح إلى هذا التطبيق'; + case 'AddProfileByLinkOrContentScreen.addFailedHandshakeException': return ({required Object p}) => 'فشلت إضافة: ${p}، يرجى فتح الوكيل أو تعديل عقدة الوكيل الحالية والمحاولة مرة أخرى'; + case 'AddProfileByScanQrcodeScanScreen.copy': return 'Copy Link'; + case 'AddProfileByScanQrcodeScanScreen.open': return 'Open Link'; + case 'AddProfileByScanQrcodeScanScreen.requestCameraPermission': return 'يرجى تمكين إذن الكاميرا'; + case 'AddProfileByScanQrcodeScanScreen.requestScreenAccess': return 'يرجى الانتقال إلى إعدادات النظام - الخصوصية والأمان - تسجيل الشاشة لإضافة أذونات لهذا التطبيق'; + case 'AddProfileByScanQrcodeScanScreen.screenshot': return 'لقطة شاشة'; + case 'AddProfileByScanQrcodeScanScreen.scanFromImage': return 'مسح من الصورة'; + case 'AddProfileByScanQrcodeScanScreen.scanNoResult': return 'فشل في تحليل الصورة ، يرجى التأكد من أن لقطة الشاشة هي رمز QR صالح'; + case 'AddProfileByScanQrcodeScanScreen.scanEmptyResult': return 'نتيجة الفحص فارغة'; + case 'AddProfileByScanQrcodeScanScreen.scanException': return ({required Object p}) => 'فشل في تحليل الصورة ، يرجى التأكد من أن لقطة الشاشة هي رمز QR صالح: ${p}'; + case 'BackupAndSyncLanSyncScreen.title': return 'LAN SYNC'; + case 'BackupAndSyncLanSyncScreen.lanSyncNotQuitTips': return 'لا تخرج من هذه الواجهة قبل اكتمال التزامن'; + case 'BackupAndSyncWebdavScreen.webdavServerUrl': return 'عنوان URL الخادم'; + case 'BackupAndSyncWebdavScreen.webdavRequired': return 'لايمكن ان يكون فارغا'; + case 'BackupAndSyncWebdavScreen.webdavLoginFailed': return 'فشل تسجيل الدخول:'; + case 'BackupAndSyncWebdavScreen.webdavListFailed': return 'فشل في الحصول على قائمة الملفات:'; + case 'DiversionGroupCustomEditScreen.invalidDomain': return ({required Object p}) => 'غير صالح [Domain]:${p}'; + case 'DiversionGroupCustomEditScreen.invalidIpCidr': return ({required Object p}) => 'غير صالح [IP Cidr]:${p}'; + case 'DiversionGroupCustomEditScreen.invalidPort': return ({required Object p}) => 'غير صالح [Port]:${p}'; + case 'DiversionGroupCustomEditScreen.invalidRuleSet': return ({required Object p}) => 'غير صالح [Rule Set]:${p}, يجب أن يكون عنوان URL عنوان URL HTTPS صالحًا وملفًا ثنائيًا مع ملحق الملف .SRS'; + case 'DiversionGroupCustomEditScreen.invalidRuleSetBuildIn': return ({required Object p}) => 'غير صالح [Rule Set(build-in)]:${p} غير صالحة، التنسيق هو geosite:xxx أو geoip:xxx أو acl:xxx، ويجب أن يكون xxx اسم قاعدة صالحًا'; + case 'DiversionGroupCustomEditScreen.setDiversionRule': return 'نصيحة: بعد الحفظ، يرجى الانتقال إلى [قواعد التحويل] لتعيين القواعد ذات الصلة، وإلا فلن تصبح سارية المفعول.'; + case 'DiversionRuleDetectScreen.title': return 'قاعدة التحويل اكتشف'; + case 'DiversionRuleDetectScreen.detect': return 'يكشف'; + case 'DiversionRuleDetectScreen.rule': return 'قاعدة:'; + case 'DiversionRuleDetectScreen.outbound': return 'مخدم بروكسي:'; + case 'DiversionRulesScreen.diversionRulesMatchTips': return 'نصيحة: حاول مطابقة القواعد من الأعلى إلى الأسفل، إذا لم تتم مطابقة أي قاعدة، استخدم [نهائي]'; + case 'DnsSettingsScreen.ispCanNotEmpty': return 'لا يمكن أن يكون ISP فارغًا'; + case 'DnsSettingsScreen.urlCanNotEmpty': return 'لا يمكن أن يكون عنوان URL فارغًا'; + case 'DnsSettingsScreen.error': return ({required Object p}) => 'نوع غير مدعوم:${p}'; + case 'DnsSettingsScreen.dnsDesc': return 'العمود الأول من بيانات التأخير هو تأخير استعلام الاتصال المباشر;\nالعمود الثاني: شغله [[حركة الوكيل]حل DNS من خلال خادم الوكيل]: بيانات التأخير هي تأخير الاستعلام الذي تم إعادة توجيهه من خلال خادم الوكيل الحالي; إذا [[حركة الوكيل]حل DNS من خلال خادم الوكيل]: بيانات التأخير هي تأخير استعلام الاتصال المباشر'; + case 'FeedbackScreen.content': return 'محتوى ردود الفعل'; + case 'FeedbackScreen.contentHit': return 'مطلوب ، ما يصل إلى 500 حرف'; + case 'FeedbackScreen.contentCannotEmpty': return 'لا يمكن أن يكون محتوى التعليقات فارغًا'; + case 'FileContentViewerScreen.title': return 'ملف محتوى الملف'; + case 'FileContentViewerScreen.chooseFile': return 'حدد الملف'; + case 'FileContentViewerScreen.clearFileContent': return 'هل أنت متأكد من مسح محتوى الملف؟'; + case 'FileContentViewerScreen.clearFileContentTips': return 'هل أنت متأكد من مسح محتوى ملف الملف الشخصي؟قد يتسبب تطهير ملف الملف الشخصي في فقدان البيانات أو وظائف التطبيق غير الطبيعية ، يرجى العمل بحذر'; + case 'HomeScreen.toSelectServer': return 'الرجاء تحديد خادم'; + case 'HomeScreen.invalidServer': return 'غير صالح ، الرجاء اختيار مرة أخرى'; + case 'HomeScreen.disabledServer': return 'معطل ، الرجاء اختيار مرة أخرى'; + case 'HomeScreen.expiredServer': return 'لا يوجد خادم متاح: قد يكون التكوين قديمًا أو معطلاً'; + case 'HomeScreen.systemProxyTips': return ({required Object sp, required Object hp}) => 'جوارب:${sp},http(s):${hp}'; + case 'HomeScreen.trafficTotal': return 'إجمالي حركة المرور'; + case 'HomeScreen.trafficProxy': return 'وكيل حركة المرور'; + case 'HomeScreen.myLinkEmpty': return 'الرجاء الإعداد [الاختصار وصلة] قبل استخدامه'; + case 'HomeScreen.deviceNoSpace': return 'مساحة غير كافيه في القرص'; + case 'HomeScreen.tooMuchServers': return ({required Object p, required Object p1}) => 'يوجد عدد كبير جدًا من الخوادم الوكيلة [${p}>${p1}]، وقد لا يكون الاتصال ممكنًا بسبب قيود ذاكرة النظام.'; + case 'LaunchFailedScreen.invalidProcess': return 'فشل التطبيق في البدء [اسم عملية غير صالح] ، يرجى إعادة تثبيت التطبيق إلى دليل منفصل'; + case 'LaunchFailedScreen.invalidProfile': return 'فشل التطبيق في البدء [فشل في الوصول إلى الملف الشخصي] ، يرجى إعادة تثبيت التطبيق'; + case 'LaunchFailedScreen.invalidVersion': return 'فشل التطبيق في بدء [إصدار غير صالح] ، يرجى إعادة تثبيت التطبيق'; + case 'LaunchFailedScreen.systemVersionLow': return 'فشل بدء تشغيل التطبيق [إصدار النظام منخفض جدًا]'; + case 'LaunchFailedScreen.invalidInstallPath': return 'مسار التثبيت غير صالح ، يرجى إعادة تثبيته إلى مسار صالح'; + case 'MyProfilesEditScreen.title': return 'تحرير الملف الشخصي'; + case 'MyProfilesEditScreen.urlExist': return 'عنوان URL موجود بالفعل ، يرجى استخدام عنوان URL آخر'; + case 'MyProfilesEditScreen.updateTimerInterval': return 'الفاصل الزمني للتحديث'; + case 'MyProfilesEditScreen.updateTimerIntervalTips': return 'الحد الأدنى: 5 م'; + case 'MyProfilesEditScreen.reloadAfterProfileUpdate': return 'إعادة التحميل بعد تحديث الملف الشخصي'; + case 'MyProfilesEditScreen.testLatencyAfterProfileUpdate': return 'ابدأ اختبارات الكمون بعد التحديث تلقائيًا'; + case 'MyProfilesEditScreen.testLatencyAfterProfileUpdateTips': return 'يجب توصيل VPN ، وتمكين [إعادة التحميل بعد تحديث الملف الشخصي]'; + case 'MyProfilesEditScreen.testLatencyAutoRemove': return 'إزالة الخوادم التي تفشل تلقائيا اختبارات الكمون'; + case 'MyProfilesEditScreen.testLatencyAutoRemoveTips': return 'جرب ما يصل إلى 3 مرات'; + case 'MyProfilesMergeScreen.profilesMerge': return 'دمج الملامح'; + case 'MyProfilesMergeScreen.profilesMergeTarget': return 'ملف تعريف الهدف'; + case 'MyProfilesMergeScreen.profilesMergeSource': return 'ملفات تعريف المصدر'; + case 'MyProfilesMergeScreen.profilesMergeTips': return 'نصيحة: سيتم تجاهل تحويل ملفات تعريف المصدر'; + case 'MyProfilesScreen.title': return 'مظهر'; + case 'MyProfilesScreen.atLeastOneEnable': return 'لا يمكن تعطيله ، يرجى الاحتفاظ بملف تعريف واحد على الأقل'; + case 'NetCheckScreen.title': return 'فحص صافي'; + case 'NetCheckScreen.warn': return 'ملاحظة: نظرًا لتأثير بيئة الشبكة وقواعد التحويل ، فإن نتائج الاختبار ليست مكافئة تمامًا للنتائج الفعلية.'; + case 'NetCheckScreen.check': return 'يفحص'; + case 'NetCheckScreen.invalidDomain': return 'اسم النطاق غير صالح'; + case 'NetCheckScreen.connectivity': return 'اتصال الشبكة'; + case 'NetCheckScreen.connectivityTestIpv4AllFailed': return ({required Object p}) => 'اختبار اتصال IPv4[${p}] كل شيء فشل'; + case 'NetCheckScreen.connectivityTestIpv4Ok': return 'Ipv4 نجح الاتصال'; + case 'NetCheckScreen.connectivityTestIpv6AllFailed': return ({required Object p}) => 'Ipv6 اختبار الاتصال [${p}] كل شيء فشل ، قد لا تدعم شبكتك IPv6'; + case 'NetCheckScreen.connectivityTestIpv6Ok': return 'نجح اتصال IPv6'; + case 'NetCheckScreen.connectivityTestOk': return 'الشبكة متصلة بالإنترنت'; + case 'NetCheckScreen.connectivityTestFailed': return 'الشبكة ليست متصلة بعد بالإنترنت'; + case 'NetCheckScreen.remoteRulesetsDownloadOk': return 'تم تنزيل كل شيء بنجاح'; + case 'NetCheckScreen.remoteRulesetsDownloadNotOk': return 'التحميل أو فشل'; + case 'NetCheckScreen.outbound': return 'مخدم بروكسي'; + case 'NetCheckScreen.outboundOk': return ({required Object p}) => '[${p}] نجح الاتصال '; + case 'NetCheckScreen.outboundFailed': return ({required Object p1, required Object p2}) => '[${p1}] فشل الاتصال\nError:[${p2}]'; + case 'NetCheckScreen.dnsServer': return 'DNS الخادم'; + case 'NetCheckScreen.dnsOk': return ({required Object p1, required Object p2, required Object p3, required Object p4}) => '[${p1}]نجح استعلام DNS\nDNS قاعدة:[${p2}]\n وقت الإستجابة:[${p3} ms]\nAعنوان[${p4}]'; + case 'NetCheckScreen.dnsFailed': return ({required Object p1, required Object p2, required Object p3}) => '[${p1}]نجح استعلام DNS\n nDNS قاعدة:[${p2}]\nخطأ:[${p3}]'; + case 'NetCheckScreen.host': return 'اتصال HTTP'; + case 'NetCheckScreen.hostConnection': return ({required Object p1, required Object p2, required Object p3}) => '[${p1}]\nقاعدة التحويل:[${p2}]\nمخدم بروكسي:[${p3}]'; + case 'NetCheckScreen.hostConnectionOk': return 'نجح الاتصال'; + case 'NetCheckScreen.hostConnectionFailed': return ({required Object p}) => 'فشل الاتصال:[${p}]'; + case 'NetConnectionsFilterScreen.title': return 'تصفية الاتصالات'; + case 'NetConnectionsFilterScreen.hostIp': return 'المجال/IP'; + case 'NetConnectionsFilterScreen.app': return 'برنامج'; + case 'NetConnectionsFilterScreen.rule': return 'قاعدة'; + case 'NetConnectionsFilterScreen.chain': return 'خارج'; + case 'NetConnectionsScreen.title': return 'روابط'; + case 'NetConnectionsScreen.copyAsCSV': return 'نسخ إلى تنسيق CSV'; + case 'NetConnectionsScreen.selectType': return 'حدد نوع التحويل'; + case 'PerAppAndroidScreen.title': return 'لكل وكيل تطبيق'; + case 'PerAppAndroidScreen.whiteListMode': return 'وضع القائمة البيضاء'; + case 'PerAppAndroidScreen.whiteListModeTip': return 'عند التمكين: فقط التطبيقات التي تم فحصها هي وكلاء ؛عندما لا يتم تمكينها: فقط التطبيقات التي لم يتم فحصها هي وكلاء'; + case 'PerAppAndroidScreen.hideSystemApp': return 'إخفاء تطبيقات النظام'; + case 'PerAppAndroidScreen.hideAppIcon': return 'إخفاء أيقونة التطبيق'; + case 'PerAppAndroidScreen.enableAppQueryPermission': return 'قم بتشغيل الإذن [استعلام قائمة التطبيقات]'; + case 'QrcodeScreen.tooLong': return 'النص طويل جدًا لعرضه'; + case 'QrcodeScreen.copy': return 'نسخ الوصلة'; + case 'QrcodeScreen.open': return 'افتح الرابط'; + case 'QrcodeScreen.share': return 'شارك الرابط'; + case 'QrcodeScreen.shareImage': return 'شارك رمز الاستجابة السريعة'; + case 'RegionSettingsScreen.title': return 'الدولة او المنطقة'; + case 'RegionSettingsScreen.Regions': return ' نصيحة: يرجى تعيين بلدك أو منطقتك الحالية بشكل صحيح ، وإلا فقد يتسبب في مشاكل في تحويل الشبكة'; + case 'ServerSelectScreen.title': return 'حدد الخادم'; + case 'ServerSelectScreen.autoSelectServer': return 'تلقائي حدد الخادم بأقل زمن انتقال'; + case 'ServerSelectScreen.recentUse': return 'مستخدم حديثا'; + case 'ServerSelectScreen.myFav': return 'المفضل لدي'; + case 'ServerSelectScreen.selectLocal': return ({required Object p}) => 'الخادم المحدد هو عنوان محلي وقد لا يعمل بشكل صحيح:${p}'; + case 'ServerSelectScreen.selectRequireEnableIPv6': return 'الخادم المحدد هو عنوان IPv6 ويتطلب [تمكين IPv6]'; + case 'ServerSelectScreen.selectDisabled': return 'تم تعطيل هذا الخادم'; + case 'ServerSelectScreen.error404': return 'واجه اكتشاف الكمون خطأ ، يرجى التحقق مما إذا كان هناك تكوين مع نفس المحتوى'; + case 'SettingsScreen.ispFaq': return ({required Object p}) => 'أسئلة مكررة[${p}]'; + case 'SettingsScreen.cleanISP': return ({required Object p}) => 'ISP واضح[${p}]'; + case 'SettingsScreen.openISP': return 'فتح ISP رابط'; + case 'SettingsScreen.cleanISPNoParam': return 'مسح معلومات مزود خدمة الإنترنت '; + case 'SettingsScreen.getTranffic': return 'احصل على حركة المرور'; + case 'SettingsScreen.tutorial': return 'درس تعليمي'; + case 'SettingsScreen.commonlyUsedRulesets': return 'مجموعات القواعد شائعة الاستخدام'; + case 'SettingsScreen.howToRemoveAds': return 'كيفية إزالة الإعلانات'; + case 'SettingsScreen.htmlBoard': return 'لوحة على الانترنت'; + case 'SettingsScreen.dnsLeakDetection': return 'كشف تسرب DNS'; + case 'SettingsScreen.speedTest': return 'اختبار السرعة'; + case 'SettingsScreen.downloadProfilePreferProxy': return 'تفضل الوكيل لتنزيل الملف الشخصي'; + case 'SettingsScreen.downloadProfilePreferProxyTips': return 'إذا كان متصلاً حاليًا ، فسيتم تنزيل الملف الشخصي من خلال الوكيل المتصالح أولاً'; + case 'SettingsScreen.rulesetDirectDownlad': return 'مجموعة القواعد تحميل مباشر'; + case 'SettingsScreen.hideUnusedDiversionGroup': return 'إخفاء مجموعات التحويل غير المستخدمة'; + case 'SettingsScreen.disableISPDiversionGroup': return 'تعطيل قواعد تحويل ISP'; + case 'SettingsScreen.portSetting': return 'ميناء'; + case 'SettingsScreen.portSettingRule': return 'القاعدة القائمة'; + case 'SettingsScreen.portSettingDirectAll': return 'توجيه كل شيء'; + case 'SettingsScreen.portSettingProxyAll': return 'وكيل الكل'; + case 'SettingsScreen.portSettingControl': return 'السيطرة والمزامنة'; + case 'SettingsScreen.portSettingCluster': return 'خدمة الكتلة'; + case 'SettingsScreen.modifyPort': return 'تعديل المنفذ'; + case 'SettingsScreen.modifyPortOccupied': return 'المنفذ مشغول، يرجى استخدام منفذ آخر'; + case 'SettingsScreen.ipStrategyTips': return 'قبل التمكين ، يرجى تأكيد أن شبكتك تدعم IPv6 ، وإلا لا يمكن الوصول إلى بعض حركة المرور بشكل طبيعي.'; + case 'SettingsScreen.tunAppendHttpProxy': return 'إلحاق وكيل HTTP إلى VPN'; + case 'SettingsScreen.tunAppendHttpProxyTips': return 'ستجاوز بعض التطبيقات جهاز NIC الظاهري والاتصال مباشرة بوكيل HTTP'; + case 'SettingsScreen.tlsInsecureEnable': return 'تخطي التحقق من الشهادة'; + case 'SettingsScreen.tlsFragmentEnable': return 'تمكين تجزئة TLS'; + case 'SettingsScreen.tlsFragmentSize': return 'حجم شريحة TLS'; + case 'SettingsScreen.tlsFragmentSleep': return 'TLS النوم المجزأ'; + case 'SettingsScreen.tlsMixedCaseSNIEnable': return 'تمكين TLS الهجين SNI'; + case 'SettingsScreen.tlsPaddingEnable': return 'تمكين الحشو TLS'; + case 'SettingsScreen.tlsPaddingSize': return 'حجم الحشو TLS'; + case 'SettingsScreen.dnsEnableRule': return 'تمكين قواعد تحويل DNS'; + case 'SettingsScreen.dnsEnableFakeIp': return 'تمكين وهمية'; + case 'SettingsScreen.dnsEnableClientSubnet': return 'تمكين ECS'; + case 'SettingsScreen.dnsEnableProxyResolveByProxy': return '[حركة الوكيل] حل DNS من خلال خادم الوكيل'; + case 'SettingsScreen.dnsEnableFinalResolveByProxy': return '[نهائي] حل DNS من خلال خادم الوكيل'; + case 'SettingsScreen.dnsTestDomain': return 'مجال الاختبار'; + case 'SettingsScreen.dnsTestDomainInvalid': return 'مجال غير صالح'; + case 'SettingsScreen.dnsTypeOutbound': return 'مخدم بروكسي'; + case 'SettingsScreen.dnsTypeDirect': return 'سير مستقيم'; + case 'SettingsScreen.dnsTypeProxy': return 'حركة الوكيل'; + case 'SettingsScreen.dnsTypeResolver': return 'خادم DNS'; + case 'SettingsScreen.dnsEnableRuleTips': return 'بعد التمكين ، سيختار اسم المجال خادم DNS المقابل للدقة وفقًا لقواعد التحويل'; + case 'SettingsScreen.dnsEnableFakeIpTips': return 'بعد تمكين FakeIP، إذا تم قطع اتصال VPN، فقد يلزم إعادة تشغيل التطبيق الخاص بك؛ يجب تشغيل هذه الوظيفة [وضع TUN]'; + case 'SettingsScreen.dnsTypeOutboundTips': return 'دقة اسم المجال لخادم الوكيل'; + case 'SettingsScreen.dnsTypeDirectTips': return 'حل اسم المجال لحركة المرور المباشرة'; + case 'SettingsScreen.dnsTypeProxyTips': return 'حل اسم المجال لحركة المرور الوكيل'; + case 'SettingsScreen.dnsTypeResolverTips': return 'دقة اسم المجال لخادم DNS الآخر'; + case 'SettingsScreen.dnsTypeFinalTips': return 'حل اسم المجال لحركة المرور الأخرى'; + case 'SettingsScreen.dnsAutoSetServer': return 'إعداد الخادم تلقائيا'; + case 'SettingsScreen.dnsResetServer': return 'إعادة تعيين الخادم'; + case 'SettingsScreen.inboundDomainResolve': return 'حل أسماء النطاقات الواردة'; + case 'SettingsScreen.privateDirect': return 'اتصال مباشر بالشبكة الخاصة'; + case 'SettingsScreen.inboundDomainResolveTips': return ({required Object p}) => 'تحتاج بعض أسماء النطاقات التي لا تحتوي على قواعد تحويل تم تكوينها إلى حلها قبل أن تتمكن من الوصول إلى قواعد التحويل المستندة إلى IP؛ وتؤثر هذه الميزة على الطلبات الواردة إلى منفذ الوكيل [${p}]'; + case 'SettingsScreen.useRomoteRes': return 'استخدم الموارد البعيدة'; + case 'SettingsScreen.autoSelect': return 'اختيار آلي'; + case 'SettingsScreen.autoSelectServerIgnorePerProxyServer': return 'تجاهل الخادم الوكيل [الوكيل الأمامي].'; + case 'SettingsScreen.autoSelectServerInterval': return 'فاصل الشيكات الكمون'; + case 'SettingsScreen.autoSelectServerReTestIfNetworkUpdate': return 'إعادة اكتشاف متى تتغير الشبكة'; + case 'SettingsScreen.autoSelectServerUpdateCurrentServerAfterManualUrltest': return 'قم بتحديث الخادم الحالي بعد الكشف اليدوي عن التأخير'; + case 'SettingsScreen.autoSelectServerIntervalTips': return 'كلما كان الفاصل الزمني لاكتشاف التأخير أقصر، كلما تم تحديث بيانات تأخير الخادم في الوقت المناسب، ولكنها ستشغل المزيد من الموارد وتستهلك الكهرباء بشكل أسرع'; + case 'SettingsScreen.autoSelectServerFavFirst': return 'PRI-Use [My Favs]'; + case 'SettingsScreen.autoSelectServerFavFirstTips': return 'إذا لم تكن قائمة [Favs] فارغة ، فاستخدم الخوادم في [Favs]'; + case 'SettingsScreen.autoSelectServerFilter': return 'تصفية خوادم غير صالحة'; + case 'SettingsScreen.autoSelectServerFilterTips': return ({required Object p}) => 'سيتم تصفية حالات فشل الكشف عن تأخير الخادم؛ إذا لم يكن هناك خادم متاح بعد التصفية، فسيتم استخدام الخوادم [${p}] الأولى بدلاً من ذلك.'; + case 'SettingsScreen.autoSelectServerLimitedNum': return 'الحد الأقصى لعدد الخوادم'; + case 'SettingsScreen.autoSelectServerLimitedNumTips': return 'سيتم تصفية الخوادم التي تتجاوز هذا الرقم'; + case 'SettingsScreen.numInvalid': return 'رقم غير صالح'; + case 'SettingsScreen.hideInvalidServer': return 'إخفاء الخوادم غير الصالحة'; + case 'SettingsScreen.sortServer': return 'خوادم الفرز'; + case 'SettingsScreen.sortServerTips': return 'فرز حسب الكمون من منخفض إلى مرتفع'; + case 'SettingsScreen.selectServerHideRecommand': return 'إخفاء [يوصي]'; + case 'SettingsScreen.selectServerHideRecent': return 'إخفاء [المستخدمة مؤخرًا]'; + case 'SettingsScreen.selectServerHideFav': return 'إخفاء [المفضلة لدي]'; + case 'SettingsScreen.homeScreen': return 'الشاشة الرئيسية'; + case 'SettingsScreen.theme': return 'Tالهيم'; + case 'SettingsScreen.myLink': return 'ارتباط اختصار'; + case 'SettingsScreen.myLinkInvalid': return 'URL غير صالح'; + case 'SettingsScreen.autoConnectAfterLaunch': return 'اتصال السيارات بعد الإطلاق'; + case 'SettingsScreen.hideAfterLaunch': return 'إخفاء النافذة بعد بدء التشغيل'; + case 'SettingsScreen.autoSetSystemProxy': return 'وكيل نظام تعيين تلقائي عند الاتصال'; + case 'SettingsScreen.disconnectWhenQuit': return 'افصل عندما يخرج التطبيق'; + case 'SettingsScreen.allowBypass': return 'السماح للتطبيقات بتجاوز VPN'; + case 'SettingsScreen.importSuccess': return 'استيراد نجاح '; + case 'SettingsScreen.rewriteConfirm': return 'سيقوم هذا الملف بكتابة التكوين المحلي الحالي.هل تريد الاستمرار؟'; + case 'SettingsScreen.networkShare': return 'مشاركة الشبكة'; + case 'SettingsScreen.frontProxy': return 'الوكيل الأمامي'; + case 'SettingsScreen.frontProxyTips': return ({required Object p}) => 'البيانات->الخادم الوكيل الأمامي [خوادم بروكسي أمامية متعددة: من الأعلى إلى الأسفل]->الخادم الوكيل [${p}]->الخادم الهدف'; + case 'SettingsScreen.allowOtherHostsConnect': return 'اسمح للآخرين بالاتصال'; + case 'SettingsScreen.allowOtherHostsConnectTips': return ({required Object sp, required Object hp}) => 'socks:${sp},http(s):${hp}'; + case 'SettingsScreen.tunAutoRoute': return 'Auto Route'; + case 'SettingsScreen.tunStrictRoute': return 'Strict Route'; + case 'SettingsScreen.tunStrictRouteTips': return 'إذا لم يتمكن الآخرون من الوصول إلى هذا الجهاز بعد تشغيل المشاركة، فيرجى محاولة إيقاف تشغيل هذا المفتاح.'; + case 'SettingsScreen.enableCluster': return 'تمكين مجموعة الوكيل الجوارب/HTTP'; + case 'SettingsScreen.clusterAllowOtherHostsConnect': return 'السماح للآخرين بالاتصال بـ CLUSTER'; + case 'SettingsScreen.clusterAllowOtherHostsConnectTips': return ({required Object ip, required Object port}) => 'http://${ip}:${port}/get_proxies'; + case 'SettingsScreen.clusterAuth': return 'مصادقة مجموعة الوكيل'; + case 'SettingsScreen.tunMode': return 'نفق وضع'; + case 'SettingsScreen.tunModeTips': return 'سيتولى وضع TUN كل حركة مرور النظام [في هذا الوضع ، يمكنك ترك وكيل النظام غير مدقلة]'; + case 'SettingsScreen.tunModeRunAsAdmin': return 'يتطلب وضع TUN أذونات مسؤول النظام ، يرجى إعادة تشغيل التطبيق كمسؤول'; + case 'SettingsScreen.tunStack': return 'Stack'; + case 'SettingsScreen.launchAtStartup': return 'إطلاق عند بدء التشغيل'; + case 'SettingsScreen.quitWhenSwitchSystemUser': return 'خروج تطبيق عند تبديل مستخدمي النظام'; + case 'SettingsScreen.handleScheme': return 'مكالمة مخطط النظام'; + case 'SettingsScreen.portableMode': return 'الوضع المحمول'; + case 'SettingsScreen.portableModeDisableTips': return 'إذا كنت بحاجة إلى الخروج من الوضع المحمول، فيرجى الخروج من [karing] وحذف المجلد [profiles] يدويًا في نفس الدليل مثل [karing.exe]'; + case 'SettingsScreen.handleKaringScheme': return 'مقبض karing:// Call'; + case 'SettingsScreen.handleClashScheme': return 'مقبض clash:// Call'; + case 'SettingsScreen.handleSingboxScheme': return 'مقبض sing-box:// يتصل'; + case 'SettingsScreen.alwayOnVPN': return 'اتصال مفتوح دائمًا'; + case 'SettingsScreen.removeSystemVPNConfig': return 'حذف تكوين VPN النظام'; + case 'SettingsScreen.timeConnectOrDisconnect': return 'المقرر يتصل/قطع الاتصال'; + case 'SettingsScreen.timeConnectOrDisconnectTips': return 'يجب أن يكون VPN متصلاً ليصبح مفيدًا ؛بعد تشغيله ، سيتم تعطيل [النوم التلقائي]'; + case 'SettingsScreen.timeConnectAndDisconnectInterval': return ({required Object p}) => 'ال cاتصاللا يمكن أن يكون فاصل الانفصال أقل من ${p} دقائق'; + case 'SettingsScreen.disableFontScaler': return 'تعطيل تحجيم الخط(إعادة التشغيل يسري)'; + case 'SettingsScreen.autoOrientation': return 'اتبع دوران الشاشة'; + case 'SettingsScreen.restartTakesEffect': return 'إعادة التشغيل يسري'; + case 'SettingsScreen.resetSettings': return 'اعادة الضبط'; + case 'SettingsScreen.cleanCache': return 'مسح ذاكرة التخزين المؤقت'; + case 'SettingsScreen.cleanCacheDone': return 'اكتملت عملية التنظيف'; + case 'SettingsScreen.appleTestFlight': return 'Apple Testflight'; + case 'SettingsScreen.appleAppStore': return 'متجر تطبيقات Apple'; + case 'SettingsScreen.hasNewVersion': return ({required Object p}) => 'تحديث الإصدار ${p}'; + case 'SettingsScreen.follow': return 'تابعنا'; + case 'SettingsScreen.contactUs': return 'اتصل بنا'; + case 'SettingsScreen.rateInApp': return 'قيمنا'; + case 'SettingsScreen.rateInAppStore': return 'قيمنا في متجر التطبيقات'; + case 'SpeedTestSettingsScreen.title': return 'URL اختبار السرعة'; + case 'TextToQrCodeScreen.title': return 'رسالة نصية إلى رمز الاستجابة السريعة'; + case 'TextToQrCodeScreen.convert': return 'يتحول'; + case 'UserAgreementScreen.privacyFirst': return 'خصوصيتك تأتي أولا'; + case 'UserAgreementScreen.agreeAndContinue': return 'قبول ومتابعة'; + case 'VersionUpdateScreen.versionReady': return ({required Object p}) => 'الإصدار الجديد [${p}] جاهز'; + case 'VersionUpdateScreen.update': return 'أعد التشغيل للتحديث'; + case 'VersionUpdateScreen.cancel': return 'ليس الآن'; + case 'CommonWidget.diableAlwayOnVPN': return 'إذا تم تشغيل [Always on VPN]، فيرجى إيقاف تشغيل [Always on VPN] ومحاولة الاتصال مرة أخرى.'; + case 'CommonWidget.resetPort': return 'الرجاء تغيير المنفذ إلى منفذ آخر متاح أو إغلاق التطبيق الذي يشغل المنفذ.'; + case 'ServerManager.noServerAvaliable': return 'لا يوجد خادم متاح، يرجى التأكد من صلاحية رابط التكوين أو ملف التكوين؛ وإذا كان التكوين الخاص بك يأتي من GitHub، فيرجى الحصول على عنوان الرابط من الزر [Raw] الموجود في الصفحة'; + case 'ServerManager.filePathCannotEmpty': return 'لا يمكن أن يكون مسار الملف فارغًا'; + case 'ServerManager.fileNotExist': return ({required Object p}) => 'الملف غير موجود: ${p}'; + case 'ServerManager.urlCannotEmpty': return 'لا يمكن أن يكون الرابط فارغًا'; + case 'ServerManager.invalidUrl': return 'رابط ملف تعريف غير صالح'; + case 'ServerManager.parseFailed': return 'فشل تحليل الملف الشخصي'; + case 'main.tray.menuOpen': return ' يفتح '; + case 'main.tray.menuExit': return ' مخرج '; + case 'enable': return 'يُمكَِن'; + case 'disable': return 'إبطال'; + case 'filter': return 'فلتر'; + case 'filterMethod': return 'طريقة التصفية'; + case 'include': return 'يشمل'; + case 'exclude': return 'استبعاد'; + case 'all': return 'الجميع'; + case 'prefer': return 'أولوية'; + case 'only': return 'فقط'; + case 'open': return 'يفتح'; + case 'close': return 'إنهاء'; + case 'quit': return 'يترك'; + case 'add': return 'اضف إليه'; + case 'remove': return 'يمسح'; + case 'edit': return 'يحرر'; + case 'view': return 'يفحص'; + case 'more': return 'أكثر'; + case 'addProfile': return 'إضافة ملف تعريف'; + case 'addSuccess': return 'اضيف بنجاح'; + case 'addSuccessThen': return ({required Object p}) => 'تم إنشاء التكوين بنجاح، يرجى الانتقال إلى [${p}] للعرض'; + case 'addFailed': return ({required Object p}) => 'إضافة فشل:${p}'; + case 'removeConfirm': return 'هل انت متأكد من الحذف؟'; + case 'tips': return 'معلومات'; + case 'copy': return 'ينسخ'; + case 'ok': return 'نعم'; + case 'cancel': return 'يلغي'; + case 'feedback': return 'تعليق'; + case 'faq': return 'أسئلة مكررة'; + case 'download': return 'تحميل'; + case 'loading': return 'تحميل...'; + case 'updateFailed': return ({required Object p}) => 'فشل التحديث:${p}'; + case 'days': return 'أيام'; + case 'hours': return 'ساعات'; + case 'minutes': return 'دقائق'; + case 'seconds': return 'ثانية'; + case 'protocol': return 'بروتوكول'; + case 'search': return 'يبحث'; + case 'custom': return 'مخصص'; + case 'connect': return 'يتصل'; + case 'disconnect': return 'قطع الاتصال'; + case 'connected': return 'متصل'; + case 'disconnected': return 'انقطع الاتصال'; + case 'connecting': return 'توصيل'; + case 'connectTimeout': return 'ربط مهلة'; + case 'timeout': return 'نفذ الوقت'; + case 'language': return 'لغة'; + case 'next': return 'التالي'; + case 'done': return 'منتهي'; + case 'apply': return 'يتقدم'; + case 'refresh': return 'ينعش'; + case 'retry': return 'إعادة المحاولة?'; + case 'none': return 'لا أحد'; + case 'reset': return 'إعادة ضبط'; + case 'submit': return 'يُقدِّم'; + case 'account': return 'حساب'; + case 'password': return 'كلمة المرور'; + case 'required': return 'مطلوب'; + case 'diversion': return 'تحويل'; + case 'diversionRules': return 'قواعد التحويل'; + case 'diversionRulesEnable': return 'تمكين قواعد تفريغ [ISP]'; + case 'diversionCustomGroup': return 'مجموعة تحويل مخصصة'; + case 'diversionCustomGroupPreset': return 'الإعداد المسبق [مجموعة تحويل مخصصة]'; + case 'diversionCustomGroupPresetTips': return 'ملاحظة: ستتم إضافة/تغطية العناصر الممكّنة إلى [مجموعة التحويل المخصصة] و[قواعد التحويل]'; + case 'diversionCustomGroupAddTips': return 'ملاحظة: قد تحتاج إلى ضبط الفرز يدويًا بعد إضافته، وإلا فإن التحويل المضاف حديثًا قد لا يسري مفعوله.'; + case 'urlTestCustomGroup': return 'مجموعة الوكيل المخصصة'; + case 'rulesetEnableTips': return 'نصيحة: بعد تشغيل الخيارات ، يرجى الانتقال إلى [قواعد التحويل] لتعيين القواعد ذات الصلة ، وإلا فلن تدخل ساري المفعول '; + case 'ispUserAgentTips': return 'سيقدم [ISP] أنواعًا مختلفة من بيانات الاشتراك بناءً على [UserAgent] في طلب [HTTP].'; + case 'ispDiversionTips': return 'قواعد التفريغ التي يوفرها [ISP]؛ لا تدعم الاشتراكات من النوع [V2Ray] قواعد التفريغ'; + case 'staticIP': return 'رقم تعريف حاسوب ثابت'; + case 'other': return 'آخر'; + case 'dns': return 'DNS'; + case 'url': return 'URL'; + case 'isp': return 'ISP'; + case 'tls': return 'TLS'; + case 'userAgent': return 'UserAgent'; + case 'urlInvalid': return 'URL غير صالح'; + case 'outboundActionCurrentSelected': return 'المحدد الحالي'; + case 'outboundActionUrltest': return 'اختيار آلي'; + case 'outboundActionDirect': return 'مباشر'; + case 'outboundActionBlock': return 'حاجز'; + case 'routeFinal': return 'أخير'; + case 'rulesetGeoSite': return 'GeoSite'; + case 'rulesetGeoIp': return 'GeoIP'; + case 'rulesetAcl': return 'ACL'; + case 'iCloud': return 'iCloud'; + case 'appleTV': return 'Apple TV'; + case 'webdav': return 'Webdav'; + case 'setting': return 'إعدادات'; + case 'protocolSniff': return 'الكشف عن البروتوكول'; + case 'protocolSniffOverrideDestination': return 'يغطي اسم المجال المكتشف عنوان هدف الاتصال'; + case 'remark': return 'ملاحظة'; + case 'remarkCannotEmpty': return 'لا يمكن أن تكون الملاحظات فارغة'; + case 'remarkTooLong': return 'ملاحظات تصل إلى 32 حرفًا'; + case 'remarkExist': return 'ملاحظة موجودة بالفعل ، يرجى استخدام اسم آخر'; + case 'domainSuffix': return 'لاحقة اسم المجال'; + case 'domain': return 'اسم النطاق'; + case 'domainKeyword': return 'الكلمات الرئيسية لاسم المجال'; + case 'domainRegex': return 'انتظام اسم المجال'; + case 'ip': return 'IP'; + case 'port': return 'ميناء'; + case 'appPackage': return 'اسم حزمة التطبيق'; + case 'processName': return 'اسم العملية'; + case 'processPath': return 'مسار العملية'; + case 'systemProxy': return 'وكيل النظام'; + case 'netInterfaces': return 'واجهات صافية'; + case 'netSpeed': return 'سرعة'; + case 'website': return 'موقع إلكتروني'; + case 'rule': return 'قاعدة'; + case 'global': return 'عالمي'; + case 'qrcode': return 'رمز الاستجابة السريعة'; + case 'scanQrcode': return 'مسح رمز الاستجابة السريعة'; + case 'scanResult': return 'نتيجة المسح'; + case 'backupAndSync': return 'النسخ الاحتياطي والمزامنة'; + case 'importAndExport': return 'استيراد وتصدير'; + case 'import': return 'يستورد'; + case 'export': return 'يصدّر'; + case 'send': return 'يرسل'; + case 'receive': return 'تولي'; + case 'sendOrReceiveNotMatch': return ({required Object p}) => 'الرجاء استخدام [${p}]'; + case 'sendConfirm': return 'تأكيد الإرسال؟'; + case 'termOfUse': return 'شرط الخدمة'; + case 'privacyPolicy': return 'سياسة الخصوصية'; + case 'about': return 'عن'; + case 'name': return 'اسم'; + case 'version': return 'إصدار'; + case 'notice': return 'يلاحظ'; + case 'sort': return 'إعادة ترتيب'; + case 'novice': return 'وضع المبتدئ'; + case 'recommended': return 'يوصي'; + case 'innerError': return ({required Object p}) => 'خطأ داخلي: ${p}'; + case 'logicOperation': return 'عملية منطقية'; + case 'share': return 'يشارك'; + case 'candidateWord': return 'كلمات المرشح'; + case 'keywordOrRegx': return 'الكلمات الرئيسية/العادية'; + case 'importFromClipboard': return 'استيراد من الحافظة'; + case 'exportToClipboard': return 'تصدير إلى الحافظة'; + case 'server': return 'الخادم'; + case 'appleTVConnectTurnOfprivateDirect': return 'يرجى تمكين [الاتصال المباشر بالشبكة الخاصة] أولاً'; + case 'targetConnectFailed': return ({required Object p}) => 'فشل الاتصال بـ [${p}]، يرجى التأكد من وجود الجهاز في نفس الشبكة المحلية (LAN) وتمكين [الاتصال المباشر بالشبكة الخاصة]'; + case 'appleTVSync': return 'مزامنة التكوين الأساسي الحالي مع Apple TV - Karing'; + case 'appleTVSyncDone': return 'اكتملت المزامنة، برجاء الانتقال إلى Apple TV - Karing لفتح/إعادة تشغيل الاتصال'; + case 'appleTVRemoveCoreConfig': return 'إزالة Apple TV - Karing Core Configuration'; + case 'appleTVRemoveCoreConfigDone': return 'Apple TV - تم حذف الملف التعريفي الأساسي لـ Karing؛ وتم قطع اتصال خدمة VPN'; + case 'appleTVUrlInvalid': return 'عنوان URL غير صالح، يرجى فتح Apple TV - Karing، ومسح رمز QR الذي يعرضه Karing'; + case 'remoteProfileEditConfirm': return 'بعد تحديث التكوين، ستتم استعادة تعديلات العقدة. هل تريد المتابعة؟'; + case 'invalidFileType': return ({required Object p}) => 'نوع الملف غير صالح:${p}'; + case 'mustBeValidHttpsURL': return 'يجب أن يكون عنوان URL HTTPS صالح'; + case 'fileNotExistReinstall': return ({required Object p}) => 'الملف مفقود [${p}]، يرجى إعادة التثبيت'; + case 'latencyTest': return 'كشف التأخير'; + case 'latencyTestResolveIP': return 'أثناء الكشف اليدوي، يتم أيضًا تحليل عنوان IP الخاص بالتصدير.'; + case 'uwpExemption': return 'إعفاء عزل شبكة UWP'; + case 'removeBannerAds': return 'إزالة الإعلانات'; + case 'removeBannerAdsByReward': return 'شاهد بضع ثوانٍ من الإعلانات التجارية وستتم مكافأتك بـ 7 أيام من عدم وجود إعلانات تجارية'; + case 'removeBannerAdsByRewardDone': return 'حصلت على مكافأة خالية من الإعلانات لمدة 7 أيام'; + case 'locales.en': return 'English'; + case 'locales.zh-CN': return '简体中文'; + case 'locales.ar': return 'عربي'; + case 'locales.ru': return 'Русский'; + case 'locales.fa': return 'فارسی'; + default: return null; + } + } +} + diff --git a/lib/i18n/strings_ar.i18n.json b/lib/i18n/strings_ar.i18n.json index c8cc603..2110181 100644 --- a/lib/i18n/strings_ar.i18n.json +++ b/lib/i18n/strings_ar.i18n.json @@ -20,7 +20,7 @@ "AddProfileByLinkOrContentScreen": { "title": "إضافة رابط ملف التعريف", "updateTimerInterval": "الفاصل الزمني للتحديث", - "updateTimerIntervalTips": "لتعطيل من فضلك ضبط على:<5m", + "updateTimerIntervalTips": "الحد الأدنى: 5 م", "profileLinkContent": "رابط/محتوى الملف الشخصي", "profileLinkContentHit": "ارتباط ملف التعريف/المحتوى [مطلوب] (دعم الدعم ، V2Ray (مدعوم الدفعة) ، خبأ ، karing ، sing-box ، shadowsocks ، روابط الملف الشخصي الفرعي)", "subscriptionCannotEmpty": "لا يمكن أن يكون رابط الملف الشخصي فارغًا", @@ -102,13 +102,13 @@ "invalidProfile": "فشل التطبيق في البدء [فشل في الوصول إلى الملف الشخصي] ، يرجى إعادة تثبيت التطبيق", "invalidVersion": "فشل التطبيق في بدء [إصدار غير صالح] ، يرجى إعادة تثبيت التطبيق", "systemVersionLow": "فشل بدء تشغيل التطبيق [إصدار النظام منخفض جدًا]", - "startFromUNC": "مسار التثبيت غير صالح ، يرجى إعادة تثبيته إلى مسار صالح" + "invalidInstallPath": "مسار التثبيت غير صالح ، يرجى إعادة تثبيته إلى مسار صالح" }, "MyProfilesEditScreen": { "title": "تحرير الملف الشخصي", "urlExist": "عنوان URL موجود بالفعل ، يرجى استخدام عنوان URL آخر", "updateTimerInterval": "الفاصل الزمني للتحديث", - "updateTimerIntervalTips": "لتعطيل يرجى تعيين:<5m", + "updateTimerIntervalTips": "الحد الأدنى: 5 م", "reloadAfterProfileUpdate": "إعادة التحميل بعد تحديث الملف الشخصي", "testLatencyAfterProfileUpdate": "ابدأ اختبارات الكمون بعد التحديث تلقائيًا", "testLatencyAfterProfileUpdateTips": "يجب توصيل VPN ، وتمكين [إعادة التحميل بعد تحديث الملف الشخصي]", @@ -215,6 +215,7 @@ "portSettingControl": "السيطرة والمزامنة", "portSettingCluster": "خدمة الكتلة", "modifyPort": "تعديل المنفذ", + "modifyPortOccupied": "المنفذ مشغول، يرجى استخدام منفذ آخر", "ipStrategyTips": "قبل التمكين ، يرجى تأكيد أن شبكتك تدعم IPv6 ، وإلا لا يمكن الوصول إلى بعض حركة المرور بشكل طبيعي.", "tunAppendHttpProxy": "إلحاق وكيل HTTP إلى VPN", "tunAppendHttpProxyTips": "ستجاوز بعض التطبيقات جهاز NIC الظاهري والاتصال مباشرة بوكيل HTTP", @@ -277,16 +278,11 @@ "autoSetSystemProxy": "وكيل نظام تعيين تلقائي عند الاتصال", "disconnectWhenQuit": "افصل عندما يخرج التطبيق", "allowBypass": "السماح للتطبيقات بتجاوز VPN", - "lanSyncTo": "مزامنة للآخرين ", - "lanSyncFrom": "مزامنة من الآخرين", - "lanSyncScanQRcode": "مسح رمز الاستجابة السريعة للمزامنة ", - "syncToConfirm": "هل تريد تأكيد المزامنة مع الطرف الآخر؟", - "syncDone": "اكتملت المزامنة", "importSuccess": "استيراد نجاح ", "rewriteConfirm": "سيقوم هذا الملف بكتابة التكوين المحلي الحالي.هل تريد الاستمرار؟", "networkShare": "مشاركة الشبكة", "frontProxy": "الوكيل الأمامي", - "frontProxyTips": "بيانات->خادم الوكيل الأمامي->مخدم بروكسي->الخادم الهدف", + "frontProxyTips": "البيانات->الخادم الوكيل الأمامي [خوادم بروكسي أمامية متعددة: من الأعلى إلى الأسفل]->الخادم الوكيل [$p]->الخادم الهدف", "allowOtherHostsConnect": "اسمح للآخرين بالاتصال", "allowOtherHostsConnectTips": "socks:$sp,http(s):$hp", "tunAutoRoute": "Auto Route", @@ -294,9 +290,8 @@ "tunStrictRouteTips": "إذا لم يتمكن الآخرون من الوصول إلى هذا الجهاز بعد تشغيل المشاركة، فيرجى محاولة إيقاف تشغيل هذا المفتاح.", "enableCluster": "تمكين مجموعة الوكيل الجوارب/HTTP", "clusterAllowOtherHostsConnect": "السماح للآخرين بالاتصال بـ CLUSTER", - "clusterAllowOtherHostsConnectTips": "http://127.0.0.1:$hp/get_proxies", + "clusterAllowOtherHostsConnectTips": "http://$ip:$port/get_proxies", "clusterAuth": "مصادقة مجموعة الوكيل", - "clusterConfirm": "يرجى التأكيد على أنه تم فحص زمن انتقال الخوادم ، ولن يتم إنشاء خدمات الوكيل إذا لم يتم فحصها أو فحصها بشكل غير صحيح", "tunMode": "نفق وضع", "tunModeTips": "سيتولى وضع TUN كل حركة مرور النظام [في هذا الوضع ، يمكنك ترك وكيل النظام غير مدقلة]", "tunModeRunAsAdmin": "يتطلب وضع TUN أذونات مسؤول النظام ، يرجى إعادة تشغيل التطبيق كمسؤول", @@ -309,6 +304,7 @@ "handleKaringScheme": "مقبض karing:// Call", "handleClashScheme": "مقبض clash:// Call", "handleSingboxScheme": "مقبض sing-box:// يتصل", + "alwayOnVPN": "اتصال مفتوح دائمًا", "removeSystemVPNConfig": "حذف تكوين VPN النظام", "timeConnectOrDisconnect": "المقرر يتصل/قطع الاتصال", "timeConnectOrDisconnectTips": "يجب أن يكون VPN متصلاً ليصبح مفيدًا ؛بعد تشغيله ، سيتم تعطيل [النوم التلقائي]", @@ -328,17 +324,12 @@ "rateInAppStore": "قيمنا في متجر التطبيقات" }, "SpeedTestSettingsScreen": { - "title": "URL اختبار السرعة", - "error": "يجب أن يكون عنوان URL HTTPS صالح" + "title": "URL اختبار السرعة" }, "TextToQrCodeScreen": { "title": "رسالة نصية إلى رمز الاستجابة السريعة", "convert": "يتحول" }, - "UrlTestSettingsScreen": { - "title": "عنوان URL لاكتشاف التأخير", - "error": "يجب أن يكون عنوان URL HTTPS صالح" - }, "UserAgreementScreen": { "privacyFirst": "خصوصيتك تأتي أولا", "agreeAndContinue": "قبول ومتابعة" @@ -368,6 +359,11 @@ }, "enable": "يُمكَِن", "disable": "إبطال", + "filter": "فلتر", + "filterMethod": "طريقة التصفية", + "include": "يشمل", + "exclude": "استبعاد", + "all": "الجميع", "prefer": "أولوية", "only": "فقط", "open": "يفتح", @@ -477,6 +473,10 @@ "importAndExport": "استيراد وتصدير", "import": "يستورد", "export": "يصدّر", + "send": "يرسل", + "receive": "تولي", + "sendOrReceiveNotMatch": "الرجاء استخدام [$p]", + "sendConfirm": "تأكيد الإرسال؟", "termOfUse": "شرط الخدمة", "privacyPolicy": "سياسة الخصوصية", "about": "عن", @@ -490,7 +490,7 @@ "logicOperation": "عملية منطقية", "share": "يشارك", "candidateWord": "كلمات المرشح", - "keywordsOrRegx": "الكلمات الرئيسية/العادية", + "keywordOrRegx": "الكلمات الرئيسية/العادية", "importFromClipboard": "استيراد من الحافظة", "exportToClipboard": "تصدير إلى الحافظة", "server": "الخادم", @@ -503,6 +503,14 @@ "appleTVUrlInvalid": "عنوان URL غير صالح، يرجى فتح Apple TV - Karing، ومسح رمز QR الذي يعرضه Karing", "remoteProfileEditConfirm": "بعد تحديث التكوين، ستتم استعادة تعديلات العقدة. هل تريد المتابعة؟", "invalidFileType": "نوع الملف غير صالح:$p", + "mustBeValidHttpsURL": "يجب أن يكون عنوان URL HTTPS صالح", + "fileNotExistReinstall": "الملف مفقود [$p]، يرجى إعادة التثبيت", + "latencyTest": "كشف التأخير", + "latencyTestResolveIP": "أثناء الكشف اليدوي، يتم أيضًا تحليل عنوان IP الخاص بالتصدير.", + "uwpExemption": "إعفاء عزل شبكة UWP", + "removeBannerAds": "إزالة الإعلانات", + "removeBannerAdsByReward": "شاهد بضع ثوانٍ من الإعلانات التجارية وستتم مكافأتك بـ 7 أيام من عدم وجود إعلانات تجارية", + "removeBannerAdsByRewardDone": "حصلت على مكافأة خالية من الإعلانات لمدة 7 أيام", "locales(map)": { "en": "English", "zh-CN": "简体中文", diff --git a/lib/i18n/strings_en.g.dart b/lib/i18n/strings_en.g.dart new file mode 100644 index 0000000..d5aff02 --- /dev/null +++ b/lib/i18n/strings_en.g.dart @@ -0,0 +1,1285 @@ +/// +/// Generated file. Do not edit. +/// +// coverage:ignore-file +// ignore_for_file: type=lint, unused_import + +part of 'strings.g.dart'; + +// Path: +typedef TranslationsEn = Translations; // ignore: unused_element +class Translations implements BaseTranslations { + /// Returns the current translations of the given [context]. + /// + /// Usage: + /// final t = Translations.of(context); + static Translations of(BuildContext context) => InheritedLocaleData.of(context).translations; + + /// You can call this constructor and build your own translation instance of this locale. + /// Constructing via the enum [AppLocale.build] is preferred. + Translations({Map? overrides, PluralResolver? cardinalResolver, PluralResolver? ordinalResolver}) + : assert(overrides == null, 'Set "translation_overrides: true" in order to enable this feature.'), + $meta = TranslationMetadata( + locale: AppLocale.en, + overrides: overrides ?? {}, + cardinalResolver: cardinalResolver, + ordinalResolver: ordinalResolver, + ) { + $meta.setFlatMapFunction(_flatMapFunction); + } + + /// Metadata for the translations of . + @override final TranslationMetadata $meta; + + /// Access flat map + dynamic operator[](String key) => $meta.getTranslation(key); + + late final Translations _root = this; // ignore: unused_field + + // Translations + late final TranslationsAboutScreenEn AboutScreen = TranslationsAboutScreenEn._(_root); + late final TranslationsAddProfileByImportFromFileScreenEn AddProfileByImportFromFileScreen = TranslationsAddProfileByImportFromFileScreenEn._(_root); + late final TranslationsAddProfileByLinkOrContentScreenEn AddProfileByLinkOrContentScreen = TranslationsAddProfileByLinkOrContentScreenEn._(_root); + late final TranslationsAddProfileByScanQrcodeScanScreenEn AddProfileByScanQrcodeScanScreen = TranslationsAddProfileByScanQrcodeScanScreenEn._(_root); + late final TranslationsBackupAndSyncLanSyncScreenEn BackupAndSyncLanSyncScreen = TranslationsBackupAndSyncLanSyncScreenEn._(_root); + late final TranslationsBackupAndSyncWebdavScreenEn BackupAndSyncWebdavScreen = TranslationsBackupAndSyncWebdavScreenEn._(_root); + late final TranslationsDiversionGroupCustomEditScreenEn DiversionGroupCustomEditScreen = TranslationsDiversionGroupCustomEditScreenEn._(_root); + late final TranslationsDiversionRuleDetectScreenEn DiversionRuleDetectScreen = TranslationsDiversionRuleDetectScreenEn._(_root); + late final TranslationsDiversionRulesScreenEn DiversionRulesScreen = TranslationsDiversionRulesScreenEn._(_root); + late final TranslationsDnsSettingsScreenEn DnsSettingsScreen = TranslationsDnsSettingsScreenEn._(_root); + late final TranslationsFeedbackScreenEn FeedbackScreen = TranslationsFeedbackScreenEn._(_root); + late final TranslationsFileContentViewerScreenEn FileContentViewerScreen = TranslationsFileContentViewerScreenEn._(_root); + late final TranslationsHomeScreenEn HomeScreen = TranslationsHomeScreenEn._(_root); + late final TranslationsLaunchFailedScreenEn LaunchFailedScreen = TranslationsLaunchFailedScreenEn._(_root); + late final TranslationsMyProfilesEditScreenEn MyProfilesEditScreen = TranslationsMyProfilesEditScreenEn._(_root); + late final TranslationsMyProfilesMergeScreenEn MyProfilesMergeScreen = TranslationsMyProfilesMergeScreenEn._(_root); + late final TranslationsMyProfilesScreenEn MyProfilesScreen = TranslationsMyProfilesScreenEn._(_root); + late final TranslationsNetCheckScreenEn NetCheckScreen = TranslationsNetCheckScreenEn._(_root); + late final TranslationsNetConnectionsFilterScreenEn NetConnectionsFilterScreen = TranslationsNetConnectionsFilterScreenEn._(_root); + late final TranslationsNetConnectionsScreenEn NetConnectionsScreen = TranslationsNetConnectionsScreenEn._(_root); + late final TranslationsPerAppAndroidScreenEn PerAppAndroidScreen = TranslationsPerAppAndroidScreenEn._(_root); + late final TranslationsQrcodeScreenEn QrcodeScreen = TranslationsQrcodeScreenEn._(_root); + late final TranslationsRegionSettingsScreenEn RegionSettingsScreen = TranslationsRegionSettingsScreenEn._(_root); + late final TranslationsServerSelectScreenEn ServerSelectScreen = TranslationsServerSelectScreenEn._(_root); + late final TranslationsSettingsScreenEn SettingsScreen = TranslationsSettingsScreenEn._(_root); + late final TranslationsSpeedTestSettingsScreenEn SpeedTestSettingsScreen = TranslationsSpeedTestSettingsScreenEn._(_root); + late final TranslationsTextToQrCodeScreenEn TextToQrCodeScreen = TranslationsTextToQrCodeScreenEn._(_root); + late final TranslationsUserAgreementScreenEn UserAgreementScreen = TranslationsUserAgreementScreenEn._(_root); + late final TranslationsVersionUpdateScreenEn VersionUpdateScreen = TranslationsVersionUpdateScreenEn._(_root); + late final TranslationsCommonWidgetEn CommonWidget = TranslationsCommonWidgetEn._(_root); + late final TranslationsServerManagerEn ServerManager = TranslationsServerManagerEn._(_root); + late final TranslationsMainEn main = TranslationsMainEn._(_root); + String get enable => 'Enable'; + String get disable => 'Disable'; + String get filter => 'Filter'; + String get filterMethod => 'Filter Method'; + String get include => 'Include'; + String get exclude => 'Exclude'; + String get all => 'All'; + String get prefer => 'Prefer'; + String get only => 'Only'; + String get open => 'Open'; + String get close => 'Close'; + String get quit => 'Quit'; + String get add => 'Add'; + String get remove => 'Remove'; + String get edit => 'Edit'; + String get view => 'View'; + String get more => 'More'; + String get addProfile => 'Add Profile'; + String get addSuccess => 'Added successfully'; + String addSuccessThen({required Object p}) => 'Profile generated successfully, please go to [${p}] to view'; + String addFailed({required Object p}) => 'Add failed:${p}'; + String get removeConfirm => 'Are you sure to delete?'; + String get tips => 'Info'; + String get copy => 'Copy'; + String get ok => 'Ok'; + String get cancel => 'Cancel'; + String get feedback => 'Feedback'; + String get faq => 'FAQ'; + String get download => 'Download'; + String get loading => 'Loading...'; + String updateFailed({required Object p}) => 'Update failed:${p}'; + String get days => 'Days'; + String get hours => 'Hours'; + String get minutes => 'Minutes'; + String get seconds => 'Seconds'; + String get protocol => 'Protocol'; + String get search => 'Search'; + String get custom => 'Custom'; + String get connect => 'Connect'; + String get disconnect => 'Disconnect'; + String get connected => 'Connected'; + String get disconnected => 'Disconnected'; + String get connecting => 'Connecting'; + String get connectTimeout => 'Connect Timeout'; + String get timeout => 'Timeout'; + String get language => 'Language'; + String get next => 'Next'; + String get done => 'Done'; + String get apply => 'Apply'; + String get refresh => 'Refresh'; + String get retry => 'Retry?'; + String get none => 'None'; + String get reset => 'Reset'; + String get submit => 'Submit'; + String get account => 'Account'; + String get password => 'Password'; + String get required => 'Required'; + String get diversion => 'Diversion'; + String get diversionRules => 'Diversion Rules'; + String get diversionRulesEnable => 'Enable [ISP] Diversion Rules'; + String get diversionCustomGroup => 'Custom Diversion Group'; + String get diversionCustomGroupPreset => 'Preset [Custom Diversion Group]'; + String get diversionCustomGroupPresetTips => 'Note: Enabled items will be added/overwritten to [Custom Diversion Group] and [Diversion Rules]'; + String get diversionCustomGroupAddTips => 'Note: After adding, you may need to manually adjust the order, otherwise the newly added diversion may not take effect'; + String get urlTestCustomGroup => 'Custom Proxy Group'; + String get rulesetEnableTips => 'Tip: After turning on the options, please go to[Diversion Rules]to set the relevant rules, otherwise they will not take effect'; + String get ispUserAgentTips => '[ISP] will send data of different subscription types based on [UserAgent] in [HTTP] request'; + String get ispDiversionTips => '[ISP] provides traffic diversion rules; [V2Ray] type subscriptions do not support traffic diversion rules'; + String get staticIP => 'Static IP'; + String get other => 'Other'; + String get dns => 'DNS'; + String get url => 'URL'; + String get isp => 'ISP'; + String get tls => 'TLS'; + String get userAgent => 'UserAgent'; + String get urlInvalid => 'Invalid URL'; + String get outboundActionCurrentSelected => 'Current Selected'; + String get outboundActionUrltest => 'Auto Select'; + String get outboundActionDirect => 'Direct'; + String get outboundActionBlock => 'Block'; + String get routeFinal => 'final'; + String get rulesetGeoSite => 'GeoSite'; + String get rulesetGeoIp => 'GeoIP'; + String get rulesetAcl => 'ACL'; + String get iCloud => 'iCloud'; + String get appleTV => 'Apple TV'; + String get webdav => 'Webdav'; + String get setting => 'Settings'; + String get protocolSniff => 'Protocol Sniff'; + String get protocolSniffOverrideDestination => 'The Sniff domain name override the connection target address'; + String get remark => 'Remark'; + String get remarkCannotEmpty => 'Remarks can not be empty'; + String get remarkTooLong => 'Remarks up to 32 characters'; + String get remarkExist => 'Remark already exists, please use another name'; + String get domainSuffix => 'Domain Suffix'; + String get domain => 'Domain'; + String get domainKeyword => 'Domain Keyword'; + String get domainRegex => 'Domain Regex'; + String get ip => 'IP'; + String get port => 'Port'; + String get appPackage => 'App Package Name'; + String get processName => 'Process Name'; + String get processPath => 'Process Path'; + String get systemProxy => 'System Proxy'; + String get netInterfaces => 'Net Interfaces'; + String get netSpeed => 'Speed'; + String get website => 'Website'; + String get rule => 'Rule'; + String get global => 'Global'; + String get qrcode => 'QR Code'; + String get scanQrcode => 'Scan QR Code'; + String get scanResult => 'Scan Result'; + String get backupAndSync => 'Backup and Sync'; + String get importAndExport => 'Import and Export'; + String get import => 'Import'; + String get export => 'Export'; + String get send => 'Send'; + String get receive => 'Receive'; + String sendOrReceiveNotMatch({required Object p}) => 'Please use [${p}]'; + String get sendConfirm => 'Confirm to send?'; + String get termOfUse => 'Terms of Service'; + String get privacyPolicy => 'Privacy & Policy'; + String get about => 'About'; + String get name => 'Name'; + String get version => 'Version'; + String get notice => 'Notice'; + String get sort => 'Reorder'; + String get novice => 'Novice Mode'; + String get recommended => 'Recommend'; + String innerError({required Object p}) => 'Inner Error:${p}'; + String get logicOperation => 'Logic Operation'; + String get share => 'Share'; + String get candidateWord => 'Candidate Words'; + String get keywordOrRegx => 'Keywords/Regular'; + String get importFromClipboard => 'Import From Clipboard'; + String get exportToClipboard => 'Export to Clipboard'; + String get server => 'Server'; + String get appleTVConnectTurnOfprivateDirect => 'Please turn on [Private network direct connection] first'; + String targetConnectFailed({required Object p}) => 'Failed to connect to [${p}]. Please make sure the devices are in the same LAN and enable [Private Network Direct Connection]'; + String get appleTVSync => 'Synchronize the current core configuration to Apple TV - Karing'; + String get appleTVSyncDone => 'Synchronization is complete. Please go to Apple TV - Karing to start the connection/restart the connection'; + String get appleTVRemoveCoreConfig => 'Delete Apple TV - Karing Core Configuration'; + String get appleTVRemoveCoreConfigDone => 'Apple TV - Karing\'s Core Configuration deleted; VPN service disconnected'; + String get appleTVUrlInvalid => 'Invalid URL, please open Apple TV - Karing and scan the QR code displayed by Karing'; + String get remoteProfileEditConfirm => 'After the Profile is updated, the node changes will be restored. Continue?'; + String invalidFileType({required Object p}) => 'Invalid file type:${p}'; + String get mustBeValidHttpsURL => 'Must be Valid https URL'; + String fileNotExistReinstall({required Object p}) => 'File missing [${p}], please reinstall'; + String get latencyTest => 'Latency Checks'; + String get latencyTestResolveIP => 'When manually checking, resolve the outlet IP'; + String get uwpExemption => 'UWP Network Isolation Exemptions'; + String get removeBannerAds => 'Remove ads'; + String get removeBannerAdsByReward => 'Watch a few seconds of advertising and you will get 7 days of ad-free rewards'; + String get removeBannerAdsByRewardDone => 'Received 7 days of ad-free reward'; + Map get locales => { + 'en': 'English', + 'zh-CN': '简体中文', + 'ar': 'عربي', + 'ru': 'Русский', + 'fa': 'فارسی', + }; +} + +// Path: AboutScreen +class TranslationsAboutScreenEn { + TranslationsAboutScreenEn._(this._root); + + final Translations _root; // ignore: unused_field + + // Translations + String get installRefer => 'Install Refer'; + String get versionChannel => 'Auto Update Channel'; + String get disableUAReport => 'Turn Off Action Data Report'; + String get disableUAReportTip => 'Behavioral data reporting helps us improve the product experience; versions lower than the main version will automatically turn off all data reporting (except [App Activation])'; + String get devOptions => 'Developer Options'; + String get enableDebugLog => 'Enable Debug Log'; + String get viewFilsContent => 'View Files'; + String get enablePprof => 'Enable pprof'; + String get pprofPanel => 'pprof Panel'; + String get openDir => 'Open File Directory'; + String get useOriginalSBProfile => 'Use original sing-box Profile'; +} + +// Path: AddProfileByImportFromFileScreen +class TranslationsAddProfileByImportFromFileScreenEn { + TranslationsAddProfileByImportFromFileScreenEn._(this._root); + + final Translations _root; // ignore: unused_field + + // Translations + String get title => 'Import Profile File'; + String get chooseFile => 'Select File'; + String get configExist => 'The Profile already exists, please do not add it repeatedly'; +} + +// Path: AddProfileByLinkOrContentScreen +class TranslationsAddProfileByLinkOrContentScreenEn { + TranslationsAddProfileByLinkOrContentScreenEn._(this._root); + + final Translations _root; // ignore: unused_field + + // Translations + String get title => 'Add Profile Link'; + String get updateTimerInterval => 'Update interval'; + String get updateTimerIntervalTips => 'Minimum: 5m'; + String get profileLinkContent => 'Profile Link/Content'; + String get profileLinkContentHit => 'Profile Link/Content [Required] (Support Clash,V2ray(batch supported),Stash,Karing,Sing-box,Shadowsocks,Sub Profile links)'; + String get subscriptionCannotEmpty => 'Profile Link can not be empty'; + String get configExist => 'The Profile already exists, please do not add it repeatedly'; + String get invalidUrl => 'The Profile Link is too long'; + String addFailedFormatException({required Object p}) => 'The format is wrong, please correct it and add it again:${p}'; + String addFailedThenDownloadAndImport({required Object p}) => 'Add failed: ${p}, please try to modify the [UserAgent] and try again, or use the device\'s built-in browser to open the configuration link and import the configuration file downloaded by the browser into this application'; + String addFailedHandshakeException({required Object p}) => 'Add failed: ${p}, please tun on the proxy or modify the current proxy node and try again'; +} + +// Path: AddProfileByScanQrcodeScanScreen +class TranslationsAddProfileByScanQrcodeScanScreenEn { + TranslationsAddProfileByScanQrcodeScanScreenEn._(this._root); + + final Translations _root; // ignore: unused_field + + // Translations + String get copy => 'Copy Link'; + String get open => 'Open Link'; + String get requestCameraPermission => 'Please enable camera permission'; + String get requestScreenAccess => 'Please go to System Settings - Privacy and Security - Screen Recording to add permissions for this application'; + String get screenshot => 'Screenshot'; + String get scanFromImage => 'Scan From Image'; + String get scanNoResult => 'Failed to parse the image, please make sure the screenshot is a valid QR code'; + String get scanEmptyResult => 'Scan Result is empty'; + String scanException({required Object p}) => 'Failed to parse the image, please make sure the screenshot is a valid QR code:${p}'; +} + +// Path: BackupAndSyncLanSyncScreen +class TranslationsBackupAndSyncLanSyncScreenEn { + TranslationsBackupAndSyncLanSyncScreenEn._(this._root); + + final Translations _root; // ignore: unused_field + + // Translations + String get title => 'LAN Sync'; + String get lanSyncNotQuitTips => 'Do not exit this interface before synchronization is completed'; +} + +// Path: BackupAndSyncWebdavScreen +class TranslationsBackupAndSyncWebdavScreenEn { + TranslationsBackupAndSyncWebdavScreenEn._(this._root); + + final Translations _root; // ignore: unused_field + + // Translations + String get webdavServerUrl => 'Server Url'; + String get webdavRequired => 'Can not be empty'; + String get webdavLoginFailed => 'Login failed:'; + String get webdavListFailed => 'Failed to get file list:'; +} + +// Path: DiversionGroupCustomEditScreen +class TranslationsDiversionGroupCustomEditScreenEn { + TranslationsDiversionGroupCustomEditScreenEn._(this._root); + + final Translations _root; // ignore: unused_field + + // Translations + String invalidDomain({required Object p}) => 'Invalid [Domain]:${p}'; + String invalidIpCidr({required Object p}) => 'Invalid [IP Cidr]:${p}'; + String invalidPort({required Object p}) => 'Invalid [Port]:${p}'; + String invalidRuleSet({required Object p}) => 'Invalid [Rule Set]:${p}, The URL must be a valid https URL and a binary file with the file extension .srs/.json'; + String invalidRuleSetBuildIn({required Object p}) => 'Invalid [Rule Set(build-in)]:${p}, The format is geosite:xxx or geoip:xxx or acl:xxx, and xxx should be a valid rule name'; + String get setDiversionRule => 'Tip: After saving, please go to [Diversion Rules] to set relevant rules, otherwise they will not take effect'; +} + +// Path: DiversionRuleDetectScreen +class TranslationsDiversionRuleDetectScreenEn { + TranslationsDiversionRuleDetectScreenEn._(this._root); + + final Translations _root; // ignore: unused_field + + // Translations + String get title => 'Diversion Rule Detect'; + String get detect => 'Detect'; + String get rule => 'Rule:'; + String get outbound => 'Proxy Server:'; +} + +// Path: DiversionRulesScreen +class TranslationsDiversionRulesScreenEn { + TranslationsDiversionRulesScreenEn._(this._root); + + final Translations _root; // ignore: unused_field + + // Translations + String get diversionRulesMatchTips => 'Tip: Try to match the rules from top to bottom. If no rule is matched, use [final]'; +} + +// Path: DnsSettingsScreen +class TranslationsDnsSettingsScreenEn { + TranslationsDnsSettingsScreenEn._(this._root); + + final Translations _root; // ignore: unused_field + + // Translations + String get ispCanNotEmpty => 'ISP can not be empty'; + String get urlCanNotEmpty => 'URL can not be empty'; + String error({required Object p}) => 'Unsupported type:${p}'; + String get dnsDesc => 'The first column of delay data is the direct connection query delay;\nThe second column: Turn on [[Proxy Traffic]Resolve DNS through proxy server]: the delay data is the query delay forwarded through the current proxy server; if the [[Proxy Traffic]Resolve DNS through proxy server]: The delay data is the direct connection query delay'; +} + +// Path: FeedbackScreen +class TranslationsFeedbackScreenEn { + TranslationsFeedbackScreenEn._(this._root); + + final Translations _root; // ignore: unused_field + + // Translations + String get content => 'Feedback Content'; + String get contentHit => 'Required, up to 500 characters'; + String get contentCannotEmpty => 'Feedback content can not be empty'; +} + +// Path: FileContentViewerScreen +class TranslationsFileContentViewerScreenEn { + TranslationsFileContentViewerScreenEn._(this._root); + + final Translations _root; // ignore: unused_field + + // Translations + String get title => 'File Content Viewer'; + String get chooseFile => 'Select File'; + String get clearFileContent => 'Are you sure to clear the content of the file?'; + String get clearFileContentTips => 'Are you sure to clear the content of the Profile file? Clearing the Profile file may cause data loss or abnormal application functions, please operate with caution'; +} + +// Path: HomeScreen +class TranslationsHomeScreenEn { + TranslationsHomeScreenEn._(this._root); + + final Translations _root; // ignore: unused_field + + // Translations + String get toSelectServer => 'Please Select a Server'; + String get invalidServer => 'is invalid, please choose again'; + String get disabledServer => 'is disabled, please choose again'; + String get expiredServer => 'No servers available, profiles may be expired or disabled'; + String systemProxyTips({required Object sp, required Object hp}) => 'socks:${sp},http(s):${hp}'; + String get trafficTotal => 'Traffic Total'; + String get trafficProxy => 'Traffic Proxy'; + String get myLinkEmpty => 'Please set up [Shortcut Link] before using it'; + String get deviceNoSpace => 'Not enough disk space'; + String tooMuchServers({required Object p, required Object p1}) => 'Too many proxy servers [${p}>${p1}], and the connection may fail due to system memory limitations'; +} + +// Path: LaunchFailedScreen +class TranslationsLaunchFailedScreenEn { + TranslationsLaunchFailedScreenEn._(this._root); + + final Translations _root; // ignore: unused_field + + // Translations + String get invalidProcess => 'The app failed to start [Invalid process name], please reinstall the app to a separate directory'; + String get invalidProfile => 'The app failed to start [Failed to access the profile], please reinstall the app'; + String get invalidVersion => 'The app failed to start [Invalid version], please reinstall the app'; + String get systemVersionLow => 'The app failed to start [system version too low]'; + String get invalidInstallPath => 'The installation path is invalid, please reinstall it to a valid path'; +} + +// Path: MyProfilesEditScreen +class TranslationsMyProfilesEditScreenEn { + TranslationsMyProfilesEditScreenEn._(this._root); + + final Translations _root; // ignore: unused_field + + // Translations + String get title => 'Profile Edit'; + String get urlExist => 'URL already exists, please use another URL'; + String get updateTimerInterval => 'Update interval'; + String get updateTimerIntervalTips => 'Minimum: 5m'; + String get reloadAfterProfileUpdate => 'Reload after Profile update'; + String get testLatencyAfterProfileUpdate => 'Start latency tests after Profile Automatically update'; + String get testLatencyAfterProfileUpdateTips => 'VPN needs to be connected, and [Reload after Profile update] Enabled'; + String get testLatencyAutoRemove => 'Automatically remove servers that fail latency tests'; + String get testLatencyAutoRemoveTips => 'Try up to 3 times'; +} + +// Path: MyProfilesMergeScreen +class TranslationsMyProfilesMergeScreenEn { + TranslationsMyProfilesMergeScreenEn._(this._root); + + final Translations _root; // ignore: unused_field + + // Translations + String get profilesMerge => 'Profiles Merge'; + String get profilesMergeTarget => 'Target Profile'; + String get profilesMergeSource => 'Source Profiles'; + String get profilesMergeTips => 'Tip: Diversion of the source profiles will be discarded'; +} + +// Path: MyProfilesScreen +class TranslationsMyProfilesScreenEn { + TranslationsMyProfilesScreenEn._(this._root); + + final Translations _root; // ignore: unused_field + + // Translations + String get title => 'Profiles'; + String get atLeastOneEnable => 'Cannot be disabled, please keep at least one profile enable'; +} + +// Path: NetCheckScreen +class TranslationsNetCheckScreenEn { + TranslationsNetCheckScreenEn._(this._root); + + final Translations _root; // ignore: unused_field + + // Translations + String get title => 'Net Check'; + String get warn => 'Note: Due to the influence of network environment and diversion rules, the test results are not completely equivalent to the actual results.'; + String get check => 'Check'; + String get invalidDomain => 'Invalid Domain Name'; + String get connectivity => 'Network Connectivity'; + String connectivityTestIpv4AllFailed({required Object p}) => 'Ipv4 Connection test [${p}] all failed'; + String get connectivityTestIpv4Ok => 'Ipv4 connection succeeded'; + String connectivityTestIpv6AllFailed({required Object p}) => 'Ipv6 Connection test [${p}] all failed, Your network may not support ipv6'; + String get connectivityTestIpv6Ok => 'Ipv6 connection succeeded'; + String get connectivityTestOk => 'The network is connected to the Internet'; + String get connectivityTestFailed => 'The network is not yet connected to the Internet'; + String get remoteRulesetsDownloadOk => 'All downloaded successfully'; + String get remoteRulesetsDownloadNotOk => 'Downloading or download failed'; + String get outbound => 'Proxy Server'; + String outboundOk({required Object p}) => '[${p}] connection succeeded'; + String outboundFailed({required Object p1, required Object p2}) => '[${p1}] connection failed\nError:[${p2}]'; + String get dnsServer => 'DNS Server'; + String dnsOk({required Object p1, required Object p2, required Object p3, required Object p4}) => '[${p1}]DNS query succeeded\nDNS Rule:[${p2}]\nLatency:[${p3} ms]\nAddress:[${p4}]'; + String dnsFailed({required Object p1, required Object p2, required Object p3}) => '[${p1}]DNS query succeeded\n nDNS Rule:[${p2}]\nError:[${p3}]'; + String get host => 'HTTP Connection'; + String hostConnection({required Object p1, required Object p2, required Object p3}) => '[${p1}]\nDiversionRule:[${p2}]\nProxy Server:[${p3}]'; + String get hostConnectionOk => 'connection succeeded'; + String hostConnectionFailed({required Object p}) => 'connection failed:[${p}]'; +} + +// Path: NetConnectionsFilterScreen +class TranslationsNetConnectionsFilterScreenEn { + TranslationsNetConnectionsFilterScreenEn._(this._root); + + final Translations _root; // ignore: unused_field + + // Translations + String get title => 'Connections Filter'; + String get hostIp => 'Domain/IP'; + String get app => 'App'; + String get rule => 'Rule'; + String get chain => 'Outbound'; +} + +// Path: NetConnectionsScreen +class TranslationsNetConnectionsScreenEn { + TranslationsNetConnectionsScreenEn._(this._root); + + final Translations _root; // ignore: unused_field + + // Translations + String get title => 'Connections'; + String get copyAsCSV => 'Copied to CSV format'; + String get selectType => 'Select Diversion Type'; +} + +// Path: PerAppAndroidScreen +class TranslationsPerAppAndroidScreenEn { + TranslationsPerAppAndroidScreenEn._(this._root); + + final Translations _root; // ignore: unused_field + + // Translations + String get title => 'Per-App Proxy'; + String get whiteListMode => 'Whitelist Mode'; + String get whiteListModeTip => 'When enabled: only the apps that have been checked are proxies; when not enabled: only the apps that are not checked are proxies'; + String get hideSystemApp => 'Hide System Apps'; + String get hideAppIcon => 'Hide App Icons'; + String get enableAppQueryPermission => 'Turn on [App list query] Permission'; +} + +// Path: QrcodeScreen +class TranslationsQrcodeScreenEn { + TranslationsQrcodeScreenEn._(this._root); + + final Translations _root; // ignore: unused_field + + // Translations + String get tooLong => 'The text is too long to display'; + String get copy => 'Copy Link'; + String get open => 'Open Link'; + String get share => 'Share Link'; + String get shareImage => 'Share QR Code'; +} + +// Path: RegionSettingsScreen +class TranslationsRegionSettingsScreenEn { + TranslationsRegionSettingsScreenEn._(this._root); + + final Translations _root; // ignore: unused_field + + // Translations + String get title => 'Country Or Region'; + String get Regions => 'Tip: Please set your current country or region correctly, otherwise it may cause network diversion problems'; +} + +// Path: ServerSelectScreen +class TranslationsServerSelectScreenEn { + TranslationsServerSelectScreenEn._(this._root); + + final Translations _root; // ignore: unused_field + + // Translations + String get title => 'Select Server'; + String get autoSelectServer => 'Auto select the server with the lowest latency'; + String get recentUse => 'Recently Used'; + String get myFav => 'My Favs'; + String selectLocal({required Object p}) => 'The selected server is a local address and may not work properly:${p}'; + String get selectRequireEnableIPv6 => 'The selected server is an IPv6 address and requires [Enable IPv6]'; + String get selectDisabled => 'This server has been disabled'; + String get error404 => 'Latency detection encountered an error, please check if there is a configuration with the same content'; +} + +// Path: SettingsScreen +class TranslationsSettingsScreenEn { + TranslationsSettingsScreenEn._(this._root); + + final Translations _root; // ignore: unused_field + + // Translations + String ispFaq({required Object p}) => 'FAQ[${p}]'; + String cleanISP({required Object p}) => 'Clear ISP[${p}]'; + String get openISP => 'Open ISP link'; + String get cleanISPNoParam => 'Clear ISP Info'; + String get getTranffic => 'Get Traffic'; + String get tutorial => 'Tutorial'; + String get commonlyUsedRulesets => 'Commonly Used Rulesets'; + String get howToRemoveAds => 'How to remove ads'; + String get htmlBoard => 'Online Panel'; + String get dnsLeakDetection => 'DNS Leaks Detection'; + String get speedTest => 'Speed Test'; + String get downloadProfilePreferProxy => 'Prefer Proxy to Download Profile'; + String get downloadProfilePreferProxyTips => 'If currently connected, the profile will be downloaded through the connected proxy first'; + String get rulesetDirectDownlad => 'Rule Set Direct Download'; + String get hideUnusedDiversionGroup => 'Hide Unused Diversion Groups'; + String get disableISPDiversionGroup => 'Disable ISP Diversion Rules'; + String get portSetting => 'Port'; + String get portSettingRule => 'Rule Based'; + String get portSettingDirectAll => 'Direct All'; + String get portSettingProxyAll => 'Proxy All'; + String get portSettingControl => 'Control and Sync'; + String get portSettingCluster => 'Cluster Service'; + String get modifyPort => 'Modify Port'; + String get modifyPortOccupied => 'The port is occupied, please use another port'; + String get ipStrategyTips => 'Before enabling, please confirm that your network supports IPv6, otherwise some traffic cannot be accessed normally.'; + String get tunAppendHttpProxy => 'Append HTTP Proxy to VPN'; + String get tunAppendHttpProxyTips => 'Some apps will bypass virtual NIC Device and directly connect to HTTP proxy'; + String get tlsInsecureEnable => 'Skip Certificate Verification'; + String get tlsFragmentEnable => 'Enable TLS Fragment'; + String get tlsFragmentSize => 'TLS Fragment Size'; + String get tlsFragmentSleep => 'TLS Fragment Sleep'; + String get tlsMixedCaseSNIEnable => 'Enable TLS Mixed SNI'; + String get tlsPaddingEnable => 'Enable TLS Padding'; + String get tlsPaddingSize => 'TLS Padding Size'; + String get dnsEnableRule => 'Enable DNS Diversion rules'; + String get dnsEnableFakeIp => 'Enable FakeIP'; + String get dnsEnableClientSubnet => 'Enable ECS'; + String get dnsEnableProxyResolveByProxy => '[Proxy Traffic]Resolve DNS through proxy server'; + String get dnsEnableFinalResolveByProxy => '[final]Resolve DNS through proxy server'; + String get dnsTestDomain => 'Test Domain'; + String get dnsTestDomainInvalid => 'Invalid Domain'; + String get dnsTypeOutbound => 'Proxy Server'; + String get dnsTypeDirect => 'Direct Traffic'; + String get dnsTypeProxy => 'Proxy Traffic'; + String get dnsTypeResolver => 'DNS Server'; + String get dnsEnableRuleTips => 'After enabling, the domain name will select the corresponding DNS server for resolution according to the diversion rules'; + String get dnsEnableFakeIpTips => 'After enabling FakeIP, if you disconnect from VPN, your app may need to be restarted; this feature requires [TUN mode] to be enabled'; + String get dnsTypeOutboundTips => 'Domain name resolution for Proxy Server'; + String get dnsTypeDirectTips => 'Domain name resolution for Direct Traffic'; + String get dnsTypeProxyTips => 'Domain name resolution for Proxy Traffic'; + String get dnsTypeResolverTips => 'Domain name resolution for Other DNS Server'; + String get dnsTypeFinalTips => 'Domain name resolution for Other Traffic'; + String get dnsAutoSetServer => 'Auto Setup Server'; + String get dnsResetServer => 'Reset Server'; + String get inboundDomainResolve => 'Resolve Inbound Domain names'; + String get privateDirect => 'Private Network Direct connection'; + String inboundDomainResolveTips({required Object p}) => 'Some domain names that are not configured with diversion rules need to be resolved before they can hit the IP-based diversion rules; this feature affects inbound requests to the proxy port [${p}]'; + String get useRomoteRes => 'Use Remote Resources'; + String get autoSelect => 'Auto Select'; + String get autoSelectServerIgnorePerProxyServer => 'Ignore [Per-Proxy] proxy server'; + String get autoSelectServerInterval => 'Latency Checks Interval'; + String get autoSelectServerReTestIfNetworkUpdate => 'Re-check Latency when Network Changes'; + String get autoSelectServerUpdateCurrentServerAfterManualUrltest => 'Update the Current Server after Manual Latency Check'; + String get autoSelectServerIntervalTips => 'The shorter the time interval, the more timely the server latency data updates, which will occupy more resources and consume more power'; + String get autoSelectServerFavFirst => 'Pri-Use [My Favs]'; + String get autoSelectServerFavFirstTips => 'If the [My Favs] list is not empty, Then use the servers in [My Favs]'; + String get autoSelectServerFilter => 'Filter Invalid Servers'; + String autoSelectServerFilterTips({required Object p}) => 'Server latency checks that fail will be filtered out; if no server is available after filtering, the first [${p}] servers will be used instead'; + String get autoSelectServerLimitedNum => 'Maximum number of servers'; + String get autoSelectServerLimitedNumTips => 'Servers exceeding this number will be filtered out'; + String get numInvalid => 'Invalid number'; + String get hideInvalidServer => 'Hide Invalid Servers'; + String get sortServer => 'Servers Sorting'; + String get sortServerTips => 'Sort by latency from low to high'; + String get selectServerHideRecommand => 'Hide [Recommend]'; + String get selectServerHideRecent => 'Hide [Recently Used]'; + String get selectServerHideFav => 'Hide [My Favs]'; + String get homeScreen => 'Home Screen'; + String get theme => 'Theme'; + String get myLink => 'Shortcut Link'; + String get myLinkInvalid => 'Invalid URL'; + String get autoConnectAfterLaunch => 'Auto Connection after Launch'; + String get hideAfterLaunch => 'Hide window after startup'; + String get autoSetSystemProxy => 'Auto Set System Proxy when Connected'; + String get disconnectWhenQuit => 'Disconnect when App Exits'; + String get allowBypass => 'Allow Apps to Bypass VPN'; + String get importSuccess => 'Import Success'; + String get rewriteConfirm => 'This file will overwrite the existing local configuration. Do you want to continue?'; + String get networkShare => 'Network Sharing'; + String get frontProxy => 'Per-Proxy'; + String frontProxyTips({required Object p}) => 'Data->Pre-Proxy Server [Multiple Pre-Proxy Servers: from top to bottom]->Proxy Server [${p}]->Target Server'; + String get allowOtherHostsConnect => 'Allow Others to Connect'; + String allowOtherHostsConnectTips({required Object sp, required Object hp}) => 'socks:${sp},http(s):${hp}'; + String get tunAutoRoute => 'Auto Route'; + String get tunStrictRoute => 'Strict Route'; + String get tunStrictRouteTips => 'If after turning on sharing, others cannot access this device, please try turning off this switch'; + String get enableCluster => 'Enable Socks/Http Proxy Cluster'; + String get clusterAllowOtherHostsConnect => 'Allow Others to Connect to Cluster'; + String clusterAllowOtherHostsConnectTips({required Object ip, required Object port}) => 'http://${ip}:${port}/get_proxies'; + String get clusterAuth => 'Proxy Cluster Authentication'; + String get tunMode => 'TUN Mode'; + String get tunModeTips => 'The TUN mode will take over all the traffic of the system [In this mode, you can leave the system proxy unenabled]'; + String get tunModeRunAsAdmin => 'The TUN mode requires system administrator permissions, please restart the app as an administrator'; + String get tunStack => 'Stack'; + String get launchAtStartup => 'Launch at Startup'; + String get quitWhenSwitchSystemUser => 'Exit App when Switch System Users'; + String get handleScheme => 'System Scheme Call'; + String get portableMode => 'Portable Mode'; + String get portableModeDisableTips => 'If you need to exit portable mode, please exit [karing] and manually delete the [profiles] folder in the same directory as [karing.exe]'; + String get handleKaringScheme => 'Handle karing:// Call'; + String get handleClashScheme => 'Handle clash:// Call'; + String get handleSingboxScheme => 'Handle sing-box:// Call'; + String get alwayOnVPN => 'Always-on Connection'; + String get removeSystemVPNConfig => 'Delete system VPN configuration'; + String get timeConnectOrDisconnect => 'Scheduled connect/disconnect'; + String get timeConnectOrDisconnectTips => 'VPN must be connected to take effect; after it is turned on, [Automatic Sleep] will be disabled'; + String timeConnectAndDisconnectInterval({required Object p}) => 'The connection/disconnection interval cannot be less than ${p} minutes'; + String get disableFontScaler => 'Disable Font scaling(Restart takes effect)'; + String get autoOrientation => 'Rotate with the screen'; + String get restartTakesEffect => 'Restart takes effect'; + String get resetSettings => 'Reset Settings'; + String get cleanCache => 'Cleanup Cache'; + String get cleanCacheDone => 'Cleanup completed'; + String get appleTestFlight => 'Apple TestFlight'; + String get appleAppStore => 'Apple AppStore'; + String hasNewVersion({required Object p}) => 'Update Version ${p}'; + String get follow => 'Follow Us'; + String get contactUs => 'Contact Us'; + String get rateInApp => 'Rate Us'; + String get rateInAppStore => 'Rate Us in AppStore'; +} + +// Path: SpeedTestSettingsScreen +class TranslationsSpeedTestSettingsScreenEn { + TranslationsSpeedTestSettingsScreenEn._(this._root); + + final Translations _root; // ignore: unused_field + + // Translations + String get title => 'Speed Test URL'; +} + +// Path: TextToQrCodeScreen +class TranslationsTextToQrCodeScreenEn { + TranslationsTextToQrCodeScreenEn._(this._root); + + final Translations _root; // ignore: unused_field + + // Translations + String get title => 'Text To QR Code'; + String get convert => 'Convert'; +} + +// Path: UserAgreementScreen +class TranslationsUserAgreementScreenEn { + TranslationsUserAgreementScreenEn._(this._root); + + final Translations _root; // ignore: unused_field + + // Translations + String get privacyFirst => 'Your Privacy Comes First'; + String get agreeAndContinue => 'Accept & Continue'; +} + +// Path: VersionUpdateScreen +class TranslationsVersionUpdateScreenEn { + TranslationsVersionUpdateScreenEn._(this._root); + + final Translations _root; // ignore: unused_field + + // Translations + String versionReady({required Object p}) => 'The new version[${p}] is ready'; + String get update => 'Restart To Update'; + String get cancel => 'Not Now'; +} + +// Path: CommonWidget +class TranslationsCommonWidgetEn { + TranslationsCommonWidgetEn._(this._root); + + final Translations _root; // ignore: unused_field + + // Translations + String get diableAlwayOnVPN => 'If [Always on VPN] is turned on, please turn off [Always on VPN] and try connecting again'; + String get resetPort => 'Please change the port to another available port or close the application occupying the port.'; +} + +// Path: ServerManager +class TranslationsServerManagerEn { + TranslationsServerManagerEn._(this._root); + + final Translations _root; // ignore: unused_field + + // Translations + String get noServerAvaliable => 'No server avaliable, Make sure the Profile Link or Profile File is valid; if your Profile comes from GitHub, please obtain the link from the [Raw] button on the page'; + String get filePathCannotEmpty => 'The file path can not be empty'; + String fileNotExist({required Object p}) => 'File does not exist:${p}'; + String get urlCannotEmpty => 'Link can not be empty'; + String get invalidUrl => 'Invalid Profile Link'; + String get parseFailed => 'Parsing Profile failed'; +} + +// Path: main +class TranslationsMainEn { + TranslationsMainEn._(this._root); + + final Translations _root; // ignore: unused_field + + // Translations + late final TranslationsMainTrayEn tray = TranslationsMainTrayEn._(_root); +} + +// Path: main.tray +class TranslationsMainTrayEn { + TranslationsMainTrayEn._(this._root); + + final Translations _root; // ignore: unused_field + + // Translations + String get menuOpen => ' Open '; + String get menuExit => ' Exit '; +} + +/// Flat map(s) containing all translations. +/// Only for edge cases! For simple maps, use the map function of this library. +extension on Translations { + dynamic _flatMapFunction(String path) { + switch (path) { + case 'AboutScreen.installRefer': return 'Install Refer'; + case 'AboutScreen.versionChannel': return 'Auto Update Channel'; + case 'AboutScreen.disableUAReport': return 'Turn Off Action Data Report'; + case 'AboutScreen.disableUAReportTip': return 'Behavioral data reporting helps us improve the product experience; versions lower than the main version will automatically turn off all data reporting (except [App Activation])'; + case 'AboutScreen.devOptions': return 'Developer Options'; + case 'AboutScreen.enableDebugLog': return 'Enable Debug Log'; + case 'AboutScreen.viewFilsContent': return 'View Files'; + case 'AboutScreen.enablePprof': return 'Enable pprof'; + case 'AboutScreen.pprofPanel': return 'pprof Panel'; + case 'AboutScreen.openDir': return 'Open File Directory'; + case 'AboutScreen.useOriginalSBProfile': return 'Use original sing-box Profile'; + case 'AddProfileByImportFromFileScreen.title': return 'Import Profile File'; + case 'AddProfileByImportFromFileScreen.chooseFile': return 'Select File'; + case 'AddProfileByImportFromFileScreen.configExist': return 'The Profile already exists, please do not add it repeatedly'; + case 'AddProfileByLinkOrContentScreen.title': return 'Add Profile Link'; + case 'AddProfileByLinkOrContentScreen.updateTimerInterval': return 'Update interval'; + case 'AddProfileByLinkOrContentScreen.updateTimerIntervalTips': return 'Minimum: 5m'; + case 'AddProfileByLinkOrContentScreen.profileLinkContent': return 'Profile Link/Content'; + case 'AddProfileByLinkOrContentScreen.profileLinkContentHit': return 'Profile Link/Content [Required] (Support Clash,V2ray(batch supported),Stash,Karing,Sing-box,Shadowsocks,Sub Profile links)'; + case 'AddProfileByLinkOrContentScreen.subscriptionCannotEmpty': return 'Profile Link can not be empty'; + case 'AddProfileByLinkOrContentScreen.configExist': return 'The Profile already exists, please do not add it repeatedly'; + case 'AddProfileByLinkOrContentScreen.invalidUrl': return 'The Profile Link is too long'; + case 'AddProfileByLinkOrContentScreen.addFailedFormatException': return ({required Object p}) => 'The format is wrong, please correct it and add it again:${p}'; + case 'AddProfileByLinkOrContentScreen.addFailedThenDownloadAndImport': return ({required Object p}) => 'Add failed: ${p}, please try to modify the [UserAgent] and try again, or use the device\'s built-in browser to open the configuration link and import the configuration file downloaded by the browser into this application'; + case 'AddProfileByLinkOrContentScreen.addFailedHandshakeException': return ({required Object p}) => 'Add failed: ${p}, please tun on the proxy or modify the current proxy node and try again'; + case 'AddProfileByScanQrcodeScanScreen.copy': return 'Copy Link'; + case 'AddProfileByScanQrcodeScanScreen.open': return 'Open Link'; + case 'AddProfileByScanQrcodeScanScreen.requestCameraPermission': return 'Please enable camera permission'; + case 'AddProfileByScanQrcodeScanScreen.requestScreenAccess': return 'Please go to System Settings - Privacy and Security - Screen Recording to add permissions for this application'; + case 'AddProfileByScanQrcodeScanScreen.screenshot': return 'Screenshot'; + case 'AddProfileByScanQrcodeScanScreen.scanFromImage': return 'Scan From Image'; + case 'AddProfileByScanQrcodeScanScreen.scanNoResult': return 'Failed to parse the image, please make sure the screenshot is a valid QR code'; + case 'AddProfileByScanQrcodeScanScreen.scanEmptyResult': return 'Scan Result is empty'; + case 'AddProfileByScanQrcodeScanScreen.scanException': return ({required Object p}) => 'Failed to parse the image, please make sure the screenshot is a valid QR code:${p}'; + case 'BackupAndSyncLanSyncScreen.title': return 'LAN Sync'; + case 'BackupAndSyncLanSyncScreen.lanSyncNotQuitTips': return 'Do not exit this interface before synchronization is completed'; + case 'BackupAndSyncWebdavScreen.webdavServerUrl': return 'Server Url'; + case 'BackupAndSyncWebdavScreen.webdavRequired': return 'Can not be empty'; + case 'BackupAndSyncWebdavScreen.webdavLoginFailed': return 'Login failed:'; + case 'BackupAndSyncWebdavScreen.webdavListFailed': return 'Failed to get file list:'; + case 'DiversionGroupCustomEditScreen.invalidDomain': return ({required Object p}) => 'Invalid [Domain]:${p}'; + case 'DiversionGroupCustomEditScreen.invalidIpCidr': return ({required Object p}) => 'Invalid [IP Cidr]:${p}'; + case 'DiversionGroupCustomEditScreen.invalidPort': return ({required Object p}) => 'Invalid [Port]:${p}'; + case 'DiversionGroupCustomEditScreen.invalidRuleSet': return ({required Object p}) => 'Invalid [Rule Set]:${p}, The URL must be a valid https URL and a binary file with the file extension .srs/.json'; + case 'DiversionGroupCustomEditScreen.invalidRuleSetBuildIn': return ({required Object p}) => 'Invalid [Rule Set(build-in)]:${p}, The format is geosite:xxx or geoip:xxx or acl:xxx, and xxx should be a valid rule name'; + case 'DiversionGroupCustomEditScreen.setDiversionRule': return 'Tip: After saving, please go to [Diversion Rules] to set relevant rules, otherwise they will not take effect'; + case 'DiversionRuleDetectScreen.title': return 'Diversion Rule Detect'; + case 'DiversionRuleDetectScreen.detect': return 'Detect'; + case 'DiversionRuleDetectScreen.rule': return 'Rule:'; + case 'DiversionRuleDetectScreen.outbound': return 'Proxy Server:'; + case 'DiversionRulesScreen.diversionRulesMatchTips': return 'Tip: Try to match the rules from top to bottom. If no rule is matched, use [final]'; + case 'DnsSettingsScreen.ispCanNotEmpty': return 'ISP can not be empty'; + case 'DnsSettingsScreen.urlCanNotEmpty': return 'URL can not be empty'; + case 'DnsSettingsScreen.error': return ({required Object p}) => 'Unsupported type:${p}'; + case 'DnsSettingsScreen.dnsDesc': return 'The first column of delay data is the direct connection query delay;\nThe second column: Turn on [[Proxy Traffic]Resolve DNS through proxy server]: the delay data is the query delay forwarded through the current proxy server; if the [[Proxy Traffic]Resolve DNS through proxy server]: The delay data is the direct connection query delay'; + case 'FeedbackScreen.content': return 'Feedback Content'; + case 'FeedbackScreen.contentHit': return 'Required, up to 500 characters'; + case 'FeedbackScreen.contentCannotEmpty': return 'Feedback content can not be empty'; + case 'FileContentViewerScreen.title': return 'File Content Viewer'; + case 'FileContentViewerScreen.chooseFile': return 'Select File'; + case 'FileContentViewerScreen.clearFileContent': return 'Are you sure to clear the content of the file?'; + case 'FileContentViewerScreen.clearFileContentTips': return 'Are you sure to clear the content of the Profile file? Clearing the Profile file may cause data loss or abnormal application functions, please operate with caution'; + case 'HomeScreen.toSelectServer': return 'Please Select a Server'; + case 'HomeScreen.invalidServer': return 'is invalid, please choose again'; + case 'HomeScreen.disabledServer': return 'is disabled, please choose again'; + case 'HomeScreen.expiredServer': return 'No servers available, profiles may be expired or disabled'; + case 'HomeScreen.systemProxyTips': return ({required Object sp, required Object hp}) => 'socks:${sp},http(s):${hp}'; + case 'HomeScreen.trafficTotal': return 'Traffic Total'; + case 'HomeScreen.trafficProxy': return 'Traffic Proxy'; + case 'HomeScreen.myLinkEmpty': return 'Please set up [Shortcut Link] before using it'; + case 'HomeScreen.deviceNoSpace': return 'Not enough disk space'; + case 'HomeScreen.tooMuchServers': return ({required Object p, required Object p1}) => 'Too many proxy servers [${p}>${p1}], and the connection may fail due to system memory limitations'; + case 'LaunchFailedScreen.invalidProcess': return 'The app failed to start [Invalid process name], please reinstall the app to a separate directory'; + case 'LaunchFailedScreen.invalidProfile': return 'The app failed to start [Failed to access the profile], please reinstall the app'; + case 'LaunchFailedScreen.invalidVersion': return 'The app failed to start [Invalid version], please reinstall the app'; + case 'LaunchFailedScreen.systemVersionLow': return 'The app failed to start [system version too low]'; + case 'LaunchFailedScreen.invalidInstallPath': return 'The installation path is invalid, please reinstall it to a valid path'; + case 'MyProfilesEditScreen.title': return 'Profile Edit'; + case 'MyProfilesEditScreen.urlExist': return 'URL already exists, please use another URL'; + case 'MyProfilesEditScreen.updateTimerInterval': return 'Update interval'; + case 'MyProfilesEditScreen.updateTimerIntervalTips': return 'Minimum: 5m'; + case 'MyProfilesEditScreen.reloadAfterProfileUpdate': return 'Reload after Profile update'; + case 'MyProfilesEditScreen.testLatencyAfterProfileUpdate': return 'Start latency tests after Profile Automatically update'; + case 'MyProfilesEditScreen.testLatencyAfterProfileUpdateTips': return 'VPN needs to be connected, and [Reload after Profile update] Enabled'; + case 'MyProfilesEditScreen.testLatencyAutoRemove': return 'Automatically remove servers that fail latency tests'; + case 'MyProfilesEditScreen.testLatencyAutoRemoveTips': return 'Try up to 3 times'; + case 'MyProfilesMergeScreen.profilesMerge': return 'Profiles Merge'; + case 'MyProfilesMergeScreen.profilesMergeTarget': return 'Target Profile'; + case 'MyProfilesMergeScreen.profilesMergeSource': return 'Source Profiles'; + case 'MyProfilesMergeScreen.profilesMergeTips': return 'Tip: Diversion of the source profiles will be discarded'; + case 'MyProfilesScreen.title': return 'Profiles'; + case 'MyProfilesScreen.atLeastOneEnable': return 'Cannot be disabled, please keep at least one profile enable'; + case 'NetCheckScreen.title': return 'Net Check'; + case 'NetCheckScreen.warn': return 'Note: Due to the influence of network environment and diversion rules, the test results are not completely equivalent to the actual results.'; + case 'NetCheckScreen.check': return 'Check'; + case 'NetCheckScreen.invalidDomain': return 'Invalid Domain Name'; + case 'NetCheckScreen.connectivity': return 'Network Connectivity'; + case 'NetCheckScreen.connectivityTestIpv4AllFailed': return ({required Object p}) => 'Ipv4 Connection test [${p}] all failed'; + case 'NetCheckScreen.connectivityTestIpv4Ok': return 'Ipv4 connection succeeded'; + case 'NetCheckScreen.connectivityTestIpv6AllFailed': return ({required Object p}) => 'Ipv6 Connection test [${p}] all failed, Your network may not support ipv6'; + case 'NetCheckScreen.connectivityTestIpv6Ok': return 'Ipv6 connection succeeded'; + case 'NetCheckScreen.connectivityTestOk': return 'The network is connected to the Internet'; + case 'NetCheckScreen.connectivityTestFailed': return 'The network is not yet connected to the Internet'; + case 'NetCheckScreen.remoteRulesetsDownloadOk': return 'All downloaded successfully'; + case 'NetCheckScreen.remoteRulesetsDownloadNotOk': return 'Downloading or download failed'; + case 'NetCheckScreen.outbound': return 'Proxy Server'; + case 'NetCheckScreen.outboundOk': return ({required Object p}) => '[${p}] connection succeeded'; + case 'NetCheckScreen.outboundFailed': return ({required Object p1, required Object p2}) => '[${p1}] connection failed\nError:[${p2}]'; + case 'NetCheckScreen.dnsServer': return 'DNS Server'; + case 'NetCheckScreen.dnsOk': return ({required Object p1, required Object p2, required Object p3, required Object p4}) => '[${p1}]DNS query succeeded\nDNS Rule:[${p2}]\nLatency:[${p3} ms]\nAddress:[${p4}]'; + case 'NetCheckScreen.dnsFailed': return ({required Object p1, required Object p2, required Object p3}) => '[${p1}]DNS query succeeded\n nDNS Rule:[${p2}]\nError:[${p3}]'; + case 'NetCheckScreen.host': return 'HTTP Connection'; + case 'NetCheckScreen.hostConnection': return ({required Object p1, required Object p2, required Object p3}) => '[${p1}]\nDiversionRule:[${p2}]\nProxy Server:[${p3}]'; + case 'NetCheckScreen.hostConnectionOk': return 'connection succeeded'; + case 'NetCheckScreen.hostConnectionFailed': return ({required Object p}) => 'connection failed:[${p}]'; + case 'NetConnectionsFilterScreen.title': return 'Connections Filter'; + case 'NetConnectionsFilterScreen.hostIp': return 'Domain/IP'; + case 'NetConnectionsFilterScreen.app': return 'App'; + case 'NetConnectionsFilterScreen.rule': return 'Rule'; + case 'NetConnectionsFilterScreen.chain': return 'Outbound'; + case 'NetConnectionsScreen.title': return 'Connections'; + case 'NetConnectionsScreen.copyAsCSV': return 'Copied to CSV format'; + case 'NetConnectionsScreen.selectType': return 'Select Diversion Type'; + case 'PerAppAndroidScreen.title': return 'Per-App Proxy'; + case 'PerAppAndroidScreen.whiteListMode': return 'Whitelist Mode'; + case 'PerAppAndroidScreen.whiteListModeTip': return 'When enabled: only the apps that have been checked are proxies; when not enabled: only the apps that are not checked are proxies'; + case 'PerAppAndroidScreen.hideSystemApp': return 'Hide System Apps'; + case 'PerAppAndroidScreen.hideAppIcon': return 'Hide App Icons'; + case 'PerAppAndroidScreen.enableAppQueryPermission': return 'Turn on [App list query] Permission'; + case 'QrcodeScreen.tooLong': return 'The text is too long to display'; + case 'QrcodeScreen.copy': return 'Copy Link'; + case 'QrcodeScreen.open': return 'Open Link'; + case 'QrcodeScreen.share': return 'Share Link'; + case 'QrcodeScreen.shareImage': return 'Share QR Code'; + case 'RegionSettingsScreen.title': return 'Country Or Region'; + case 'RegionSettingsScreen.Regions': return 'Tip: Please set your current country or region correctly, otherwise it may cause network diversion problems'; + case 'ServerSelectScreen.title': return 'Select Server'; + case 'ServerSelectScreen.autoSelectServer': return 'Auto select the server with the lowest latency'; + case 'ServerSelectScreen.recentUse': return 'Recently Used'; + case 'ServerSelectScreen.myFav': return 'My Favs'; + case 'ServerSelectScreen.selectLocal': return ({required Object p}) => 'The selected server is a local address and may not work properly:${p}'; + case 'ServerSelectScreen.selectRequireEnableIPv6': return 'The selected server is an IPv6 address and requires [Enable IPv6]'; + case 'ServerSelectScreen.selectDisabled': return 'This server has been disabled'; + case 'ServerSelectScreen.error404': return 'Latency detection encountered an error, please check if there is a configuration with the same content'; + case 'SettingsScreen.ispFaq': return ({required Object p}) => 'FAQ[${p}]'; + case 'SettingsScreen.cleanISP': return ({required Object p}) => 'Clear ISP[${p}]'; + case 'SettingsScreen.openISP': return 'Open ISP link'; + case 'SettingsScreen.cleanISPNoParam': return 'Clear ISP Info'; + case 'SettingsScreen.getTranffic': return 'Get Traffic'; + case 'SettingsScreen.tutorial': return 'Tutorial'; + case 'SettingsScreen.commonlyUsedRulesets': return 'Commonly Used Rulesets'; + case 'SettingsScreen.howToRemoveAds': return 'How to remove ads'; + case 'SettingsScreen.htmlBoard': return 'Online Panel'; + case 'SettingsScreen.dnsLeakDetection': return 'DNS Leaks Detection'; + case 'SettingsScreen.speedTest': return 'Speed Test'; + case 'SettingsScreen.downloadProfilePreferProxy': return 'Prefer Proxy to Download Profile'; + case 'SettingsScreen.downloadProfilePreferProxyTips': return 'If currently connected, the profile will be downloaded through the connected proxy first'; + case 'SettingsScreen.rulesetDirectDownlad': return 'Rule Set Direct Download'; + case 'SettingsScreen.hideUnusedDiversionGroup': return 'Hide Unused Diversion Groups'; + case 'SettingsScreen.disableISPDiversionGroup': return 'Disable ISP Diversion Rules'; + case 'SettingsScreen.portSetting': return 'Port'; + case 'SettingsScreen.portSettingRule': return 'Rule Based'; + case 'SettingsScreen.portSettingDirectAll': return 'Direct All'; + case 'SettingsScreen.portSettingProxyAll': return 'Proxy All'; + case 'SettingsScreen.portSettingControl': return 'Control and Sync'; + case 'SettingsScreen.portSettingCluster': return 'Cluster Service'; + case 'SettingsScreen.modifyPort': return 'Modify Port'; + case 'SettingsScreen.modifyPortOccupied': return 'The port is occupied, please use another port'; + case 'SettingsScreen.ipStrategyTips': return 'Before enabling, please confirm that your network supports IPv6, otherwise some traffic cannot be accessed normally.'; + case 'SettingsScreen.tunAppendHttpProxy': return 'Append HTTP Proxy to VPN'; + case 'SettingsScreen.tunAppendHttpProxyTips': return 'Some apps will bypass virtual NIC Device and directly connect to HTTP proxy'; + case 'SettingsScreen.tlsInsecureEnable': return 'Skip Certificate Verification'; + case 'SettingsScreen.tlsFragmentEnable': return 'Enable TLS Fragment'; + case 'SettingsScreen.tlsFragmentSize': return 'TLS Fragment Size'; + case 'SettingsScreen.tlsFragmentSleep': return 'TLS Fragment Sleep'; + case 'SettingsScreen.tlsMixedCaseSNIEnable': return 'Enable TLS Mixed SNI'; + case 'SettingsScreen.tlsPaddingEnable': return 'Enable TLS Padding'; + case 'SettingsScreen.tlsPaddingSize': return 'TLS Padding Size'; + case 'SettingsScreen.dnsEnableRule': return 'Enable DNS Diversion rules'; + case 'SettingsScreen.dnsEnableFakeIp': return 'Enable FakeIP'; + case 'SettingsScreen.dnsEnableClientSubnet': return 'Enable ECS'; + case 'SettingsScreen.dnsEnableProxyResolveByProxy': return '[Proxy Traffic]Resolve DNS through proxy server'; + case 'SettingsScreen.dnsEnableFinalResolveByProxy': return '[final]Resolve DNS through proxy server'; + case 'SettingsScreen.dnsTestDomain': return 'Test Domain'; + case 'SettingsScreen.dnsTestDomainInvalid': return 'Invalid Domain'; + case 'SettingsScreen.dnsTypeOutbound': return 'Proxy Server'; + case 'SettingsScreen.dnsTypeDirect': return 'Direct Traffic'; + case 'SettingsScreen.dnsTypeProxy': return 'Proxy Traffic'; + case 'SettingsScreen.dnsTypeResolver': return 'DNS Server'; + case 'SettingsScreen.dnsEnableRuleTips': return 'After enabling, the domain name will select the corresponding DNS server for resolution according to the diversion rules'; + case 'SettingsScreen.dnsEnableFakeIpTips': return 'After enabling FakeIP, if you disconnect from VPN, your app may need to be restarted; this feature requires [TUN mode] to be enabled'; + case 'SettingsScreen.dnsTypeOutboundTips': return 'Domain name resolution for Proxy Server'; + case 'SettingsScreen.dnsTypeDirectTips': return 'Domain name resolution for Direct Traffic'; + case 'SettingsScreen.dnsTypeProxyTips': return 'Domain name resolution for Proxy Traffic'; + case 'SettingsScreen.dnsTypeResolverTips': return 'Domain name resolution for Other DNS Server'; + case 'SettingsScreen.dnsTypeFinalTips': return 'Domain name resolution for Other Traffic'; + case 'SettingsScreen.dnsAutoSetServer': return 'Auto Setup Server'; + case 'SettingsScreen.dnsResetServer': return 'Reset Server'; + case 'SettingsScreen.inboundDomainResolve': return 'Resolve Inbound Domain names'; + case 'SettingsScreen.privateDirect': return 'Private Network Direct connection'; + case 'SettingsScreen.inboundDomainResolveTips': return ({required Object p}) => 'Some domain names that are not configured with diversion rules need to be resolved before they can hit the IP-based diversion rules; this feature affects inbound requests to the proxy port [${p}]'; + case 'SettingsScreen.useRomoteRes': return 'Use Remote Resources'; + case 'SettingsScreen.autoSelect': return 'Auto Select'; + case 'SettingsScreen.autoSelectServerIgnorePerProxyServer': return 'Ignore [Per-Proxy] proxy server'; + case 'SettingsScreen.autoSelectServerInterval': return 'Latency Checks Interval'; + case 'SettingsScreen.autoSelectServerReTestIfNetworkUpdate': return 'Re-check Latency when Network Changes'; + case 'SettingsScreen.autoSelectServerUpdateCurrentServerAfterManualUrltest': return 'Update the Current Server after Manual Latency Check'; + case 'SettingsScreen.autoSelectServerIntervalTips': return 'The shorter the time interval, the more timely the server latency data updates, which will occupy more resources and consume more power'; + case 'SettingsScreen.autoSelectServerFavFirst': return 'Pri-Use [My Favs]'; + case 'SettingsScreen.autoSelectServerFavFirstTips': return 'If the [My Favs] list is not empty, Then use the servers in [My Favs]'; + case 'SettingsScreen.autoSelectServerFilter': return 'Filter Invalid Servers'; + case 'SettingsScreen.autoSelectServerFilterTips': return ({required Object p}) => 'Server latency checks that fail will be filtered out; if no server is available after filtering, the first [${p}] servers will be used instead'; + case 'SettingsScreen.autoSelectServerLimitedNum': return 'Maximum number of servers'; + case 'SettingsScreen.autoSelectServerLimitedNumTips': return 'Servers exceeding this number will be filtered out'; + case 'SettingsScreen.numInvalid': return 'Invalid number'; + case 'SettingsScreen.hideInvalidServer': return 'Hide Invalid Servers'; + case 'SettingsScreen.sortServer': return 'Servers Sorting'; + case 'SettingsScreen.sortServerTips': return 'Sort by latency from low to high'; + case 'SettingsScreen.selectServerHideRecommand': return 'Hide [Recommend]'; + case 'SettingsScreen.selectServerHideRecent': return 'Hide [Recently Used]'; + case 'SettingsScreen.selectServerHideFav': return 'Hide [My Favs]'; + case 'SettingsScreen.homeScreen': return 'Home Screen'; + case 'SettingsScreen.theme': return 'Theme'; + case 'SettingsScreen.myLink': return 'Shortcut Link'; + case 'SettingsScreen.myLinkInvalid': return 'Invalid URL'; + case 'SettingsScreen.autoConnectAfterLaunch': return 'Auto Connection after Launch'; + case 'SettingsScreen.hideAfterLaunch': return 'Hide window after startup'; + case 'SettingsScreen.autoSetSystemProxy': return 'Auto Set System Proxy when Connected'; + case 'SettingsScreen.disconnectWhenQuit': return 'Disconnect when App Exits'; + case 'SettingsScreen.allowBypass': return 'Allow Apps to Bypass VPN'; + case 'SettingsScreen.importSuccess': return 'Import Success'; + case 'SettingsScreen.rewriteConfirm': return 'This file will overwrite the existing local configuration. Do you want to continue?'; + case 'SettingsScreen.networkShare': return 'Network Sharing'; + case 'SettingsScreen.frontProxy': return 'Per-Proxy'; + case 'SettingsScreen.frontProxyTips': return ({required Object p}) => 'Data->Pre-Proxy Server [Multiple Pre-Proxy Servers: from top to bottom]->Proxy Server [${p}]->Target Server'; + case 'SettingsScreen.allowOtherHostsConnect': return 'Allow Others to Connect'; + case 'SettingsScreen.allowOtherHostsConnectTips': return ({required Object sp, required Object hp}) => 'socks:${sp},http(s):${hp}'; + case 'SettingsScreen.tunAutoRoute': return 'Auto Route'; + case 'SettingsScreen.tunStrictRoute': return 'Strict Route'; + case 'SettingsScreen.tunStrictRouteTips': return 'If after turning on sharing, others cannot access this device, please try turning off this switch'; + case 'SettingsScreen.enableCluster': return 'Enable Socks/Http Proxy Cluster'; + case 'SettingsScreen.clusterAllowOtherHostsConnect': return 'Allow Others to Connect to Cluster'; + case 'SettingsScreen.clusterAllowOtherHostsConnectTips': return ({required Object ip, required Object port}) => 'http://${ip}:${port}/get_proxies'; + case 'SettingsScreen.clusterAuth': return 'Proxy Cluster Authentication'; + case 'SettingsScreen.tunMode': return 'TUN Mode'; + case 'SettingsScreen.tunModeTips': return 'The TUN mode will take over all the traffic of the system [In this mode, you can leave the system proxy unenabled]'; + case 'SettingsScreen.tunModeRunAsAdmin': return 'The TUN mode requires system administrator permissions, please restart the app as an administrator'; + case 'SettingsScreen.tunStack': return 'Stack'; + case 'SettingsScreen.launchAtStartup': return 'Launch at Startup'; + case 'SettingsScreen.quitWhenSwitchSystemUser': return 'Exit App when Switch System Users'; + case 'SettingsScreen.handleScheme': return 'System Scheme Call'; + case 'SettingsScreen.portableMode': return 'Portable Mode'; + case 'SettingsScreen.portableModeDisableTips': return 'If you need to exit portable mode, please exit [karing] and manually delete the [profiles] folder in the same directory as [karing.exe]'; + case 'SettingsScreen.handleKaringScheme': return 'Handle karing:// Call'; + case 'SettingsScreen.handleClashScheme': return 'Handle clash:// Call'; + case 'SettingsScreen.handleSingboxScheme': return 'Handle sing-box:// Call'; + case 'SettingsScreen.alwayOnVPN': return 'Always-on Connection'; + case 'SettingsScreen.removeSystemVPNConfig': return 'Delete system VPN configuration'; + case 'SettingsScreen.timeConnectOrDisconnect': return 'Scheduled connect/disconnect'; + case 'SettingsScreen.timeConnectOrDisconnectTips': return 'VPN must be connected to take effect; after it is turned on, [Automatic Sleep] will be disabled'; + case 'SettingsScreen.timeConnectAndDisconnectInterval': return ({required Object p}) => 'The connection/disconnection interval cannot be less than ${p} minutes'; + case 'SettingsScreen.disableFontScaler': return 'Disable Font scaling(Restart takes effect)'; + case 'SettingsScreen.autoOrientation': return 'Rotate with the screen'; + case 'SettingsScreen.restartTakesEffect': return 'Restart takes effect'; + case 'SettingsScreen.resetSettings': return 'Reset Settings'; + case 'SettingsScreen.cleanCache': return 'Cleanup Cache'; + case 'SettingsScreen.cleanCacheDone': return 'Cleanup completed'; + case 'SettingsScreen.appleTestFlight': return 'Apple TestFlight'; + case 'SettingsScreen.appleAppStore': return 'Apple AppStore'; + case 'SettingsScreen.hasNewVersion': return ({required Object p}) => 'Update Version ${p}'; + case 'SettingsScreen.follow': return 'Follow Us'; + case 'SettingsScreen.contactUs': return 'Contact Us'; + case 'SettingsScreen.rateInApp': return 'Rate Us'; + case 'SettingsScreen.rateInAppStore': return 'Rate Us in AppStore'; + case 'SpeedTestSettingsScreen.title': return 'Speed Test URL'; + case 'TextToQrCodeScreen.title': return 'Text To QR Code'; + case 'TextToQrCodeScreen.convert': return 'Convert'; + case 'UserAgreementScreen.privacyFirst': return 'Your Privacy Comes First'; + case 'UserAgreementScreen.agreeAndContinue': return 'Accept & Continue'; + case 'VersionUpdateScreen.versionReady': return ({required Object p}) => 'The new version[${p}] is ready'; + case 'VersionUpdateScreen.update': return 'Restart To Update'; + case 'VersionUpdateScreen.cancel': return 'Not Now'; + case 'CommonWidget.diableAlwayOnVPN': return 'If [Always on VPN] is turned on, please turn off [Always on VPN] and try connecting again'; + case 'CommonWidget.resetPort': return 'Please change the port to another available port or close the application occupying the port.'; + case 'ServerManager.noServerAvaliable': return 'No server avaliable, Make sure the Profile Link or Profile File is valid; if your Profile comes from GitHub, please obtain the link from the [Raw] button on the page'; + case 'ServerManager.filePathCannotEmpty': return 'The file path can not be empty'; + case 'ServerManager.fileNotExist': return ({required Object p}) => 'File does not exist:${p}'; + case 'ServerManager.urlCannotEmpty': return 'Link can not be empty'; + case 'ServerManager.invalidUrl': return 'Invalid Profile Link'; + case 'ServerManager.parseFailed': return 'Parsing Profile failed'; + case 'main.tray.menuOpen': return ' Open '; + case 'main.tray.menuExit': return ' Exit '; + case 'enable': return 'Enable'; + case 'disable': return 'Disable'; + case 'filter': return 'Filter'; + case 'filterMethod': return 'Filter Method'; + case 'include': return 'Include'; + case 'exclude': return 'Exclude'; + case 'all': return 'All'; + case 'prefer': return 'Prefer'; + case 'only': return 'Only'; + case 'open': return 'Open'; + case 'close': return 'Close'; + case 'quit': return 'Quit'; + case 'add': return 'Add'; + case 'remove': return 'Remove'; + case 'edit': return 'Edit'; + case 'view': return 'View'; + case 'more': return 'More'; + case 'addProfile': return 'Add Profile'; + case 'addSuccess': return 'Added successfully'; + case 'addSuccessThen': return ({required Object p}) => 'Profile generated successfully, please go to [${p}] to view'; + case 'addFailed': return ({required Object p}) => 'Add failed:${p}'; + case 'removeConfirm': return 'Are you sure to delete?'; + case 'tips': return 'Info'; + case 'copy': return 'Copy'; + case 'ok': return 'Ok'; + case 'cancel': return 'Cancel'; + case 'feedback': return 'Feedback'; + case 'faq': return 'FAQ'; + case 'download': return 'Download'; + case 'loading': return 'Loading...'; + case 'updateFailed': return ({required Object p}) => 'Update failed:${p}'; + case 'days': return 'Days'; + case 'hours': return 'Hours'; + case 'minutes': return 'Minutes'; + case 'seconds': return 'Seconds'; + case 'protocol': return 'Protocol'; + case 'search': return 'Search'; + case 'custom': return 'Custom'; + case 'connect': return 'Connect'; + case 'disconnect': return 'Disconnect'; + case 'connected': return 'Connected'; + case 'disconnected': return 'Disconnected'; + case 'connecting': return 'Connecting'; + case 'connectTimeout': return 'Connect Timeout'; + case 'timeout': return 'Timeout'; + case 'language': return 'Language'; + case 'next': return 'Next'; + case 'done': return 'Done'; + case 'apply': return 'Apply'; + case 'refresh': return 'Refresh'; + case 'retry': return 'Retry?'; + case 'none': return 'None'; + case 'reset': return 'Reset'; + case 'submit': return 'Submit'; + case 'account': return 'Account'; + case 'password': return 'Password'; + case 'required': return 'Required'; + case 'diversion': return 'Diversion'; + case 'diversionRules': return 'Diversion Rules'; + case 'diversionRulesEnable': return 'Enable [ISP] Diversion Rules'; + case 'diversionCustomGroup': return 'Custom Diversion Group'; + case 'diversionCustomGroupPreset': return 'Preset [Custom Diversion Group]'; + case 'diversionCustomGroupPresetTips': return 'Note: Enabled items will be added/overwritten to [Custom Diversion Group] and [Diversion Rules]'; + case 'diversionCustomGroupAddTips': return 'Note: After adding, you may need to manually adjust the order, otherwise the newly added diversion may not take effect'; + case 'urlTestCustomGroup': return 'Custom Proxy Group'; + case 'rulesetEnableTips': return 'Tip: After turning on the options, please go to[Diversion Rules]to set the relevant rules, otherwise they will not take effect'; + case 'ispUserAgentTips': return '[ISP] will send data of different subscription types based on [UserAgent] in [HTTP] request'; + case 'ispDiversionTips': return '[ISP] provides traffic diversion rules; [V2Ray] type subscriptions do not support traffic diversion rules'; + case 'staticIP': return 'Static IP'; + case 'other': return 'Other'; + case 'dns': return 'DNS'; + case 'url': return 'URL'; + case 'isp': return 'ISP'; + case 'tls': return 'TLS'; + case 'userAgent': return 'UserAgent'; + case 'urlInvalid': return 'Invalid URL'; + case 'outboundActionCurrentSelected': return 'Current Selected'; + case 'outboundActionUrltest': return 'Auto Select'; + case 'outboundActionDirect': return 'Direct'; + case 'outboundActionBlock': return 'Block'; + case 'routeFinal': return 'final'; + case 'rulesetGeoSite': return 'GeoSite'; + case 'rulesetGeoIp': return 'GeoIP'; + case 'rulesetAcl': return 'ACL'; + case 'iCloud': return 'iCloud'; + case 'appleTV': return 'Apple TV'; + case 'webdav': return 'Webdav'; + case 'setting': return 'Settings'; + case 'protocolSniff': return 'Protocol Sniff'; + case 'protocolSniffOverrideDestination': return 'The Sniff domain name override the connection target address'; + case 'remark': return 'Remark'; + case 'remarkCannotEmpty': return 'Remarks can not be empty'; + case 'remarkTooLong': return 'Remarks up to 32 characters'; + case 'remarkExist': return 'Remark already exists, please use another name'; + case 'domainSuffix': return 'Domain Suffix'; + case 'domain': return 'Domain'; + case 'domainKeyword': return 'Domain Keyword'; + case 'domainRegex': return 'Domain Regex'; + case 'ip': return 'IP'; + case 'port': return 'Port'; + case 'appPackage': return 'App Package Name'; + case 'processName': return 'Process Name'; + case 'processPath': return 'Process Path'; + case 'systemProxy': return 'System Proxy'; + case 'netInterfaces': return 'Net Interfaces'; + case 'netSpeed': return 'Speed'; + case 'website': return 'Website'; + case 'rule': return 'Rule'; + case 'global': return 'Global'; + case 'qrcode': return 'QR Code'; + case 'scanQrcode': return 'Scan QR Code'; + case 'scanResult': return 'Scan Result'; + case 'backupAndSync': return 'Backup and Sync'; + case 'importAndExport': return 'Import and Export'; + case 'import': return 'Import'; + case 'export': return 'Export'; + case 'send': return 'Send'; + case 'receive': return 'Receive'; + case 'sendOrReceiveNotMatch': return ({required Object p}) => 'Please use [${p}]'; + case 'sendConfirm': return 'Confirm to send?'; + case 'termOfUse': return 'Terms of Service'; + case 'privacyPolicy': return 'Privacy & Policy'; + case 'about': return 'About'; + case 'name': return 'Name'; + case 'version': return 'Version'; + case 'notice': return 'Notice'; + case 'sort': return 'Reorder'; + case 'novice': return 'Novice Mode'; + case 'recommended': return 'Recommend'; + case 'innerError': return ({required Object p}) => 'Inner Error:${p}'; + case 'logicOperation': return 'Logic Operation'; + case 'share': return 'Share'; + case 'candidateWord': return 'Candidate Words'; + case 'keywordOrRegx': return 'Keywords/Regular'; + case 'importFromClipboard': return 'Import From Clipboard'; + case 'exportToClipboard': return 'Export to Clipboard'; + case 'server': return 'Server'; + case 'appleTVConnectTurnOfprivateDirect': return 'Please turn on [Private network direct connection] first'; + case 'targetConnectFailed': return ({required Object p}) => 'Failed to connect to [${p}]. Please make sure the devices are in the same LAN and enable [Private Network Direct Connection]'; + case 'appleTVSync': return 'Synchronize the current core configuration to Apple TV - Karing'; + case 'appleTVSyncDone': return 'Synchronization is complete. Please go to Apple TV - Karing to start the connection/restart the connection'; + case 'appleTVRemoveCoreConfig': return 'Delete Apple TV - Karing Core Configuration'; + case 'appleTVRemoveCoreConfigDone': return 'Apple TV - Karing\'s Core Configuration deleted; VPN service disconnected'; + case 'appleTVUrlInvalid': return 'Invalid URL, please open Apple TV - Karing and scan the QR code displayed by Karing'; + case 'remoteProfileEditConfirm': return 'After the Profile is updated, the node changes will be restored. Continue?'; + case 'invalidFileType': return ({required Object p}) => 'Invalid file type:${p}'; + case 'mustBeValidHttpsURL': return 'Must be Valid https URL'; + case 'fileNotExistReinstall': return ({required Object p}) => 'File missing [${p}], please reinstall'; + case 'latencyTest': return 'Latency Checks'; + case 'latencyTestResolveIP': return 'When manually checking, resolve the outlet IP'; + case 'uwpExemption': return 'UWP Network Isolation Exemptions'; + case 'removeBannerAds': return 'Remove ads'; + case 'removeBannerAdsByReward': return 'Watch a few seconds of advertising and you will get 7 days of ad-free rewards'; + case 'removeBannerAdsByRewardDone': return 'Received 7 days of ad-free reward'; + case 'locales.en': return 'English'; + case 'locales.zh-CN': return '简体中文'; + case 'locales.ar': return 'عربي'; + case 'locales.ru': return 'Русский'; + case 'locales.fa': return 'فارسی'; + default: return null; + } + } +} + diff --git a/lib/i18n/strings_fa.g.dart b/lib/i18n/strings_fa.g.dart new file mode 100644 index 0000000..d078ee9 --- /dev/null +++ b/lib/i18n/strings_fa.g.dart @@ -0,0 +1,1281 @@ +/// +/// Generated file. Do not edit. +/// +// coverage:ignore-file +// ignore_for_file: type=lint, unused_import + +import 'package:flutter/widgets.dart'; +import 'package:intl/intl.dart'; +import 'package:slang/generated.dart'; +import 'strings.g.dart'; + +// Path: +class TranslationsFa implements Translations { + /// You can call this constructor and build your own translation instance of this locale. + /// Constructing via the enum [AppLocale.build] is preferred. + TranslationsFa({Map? overrides, PluralResolver? cardinalResolver, PluralResolver? ordinalResolver}) + : assert(overrides == null, 'Set "translation_overrides: true" in order to enable this feature.'), + $meta = TranslationMetadata( + locale: AppLocale.fa, + overrides: overrides ?? {}, + cardinalResolver: cardinalResolver, + ordinalResolver: ordinalResolver, + ) { + $meta.setFlatMapFunction(_flatMapFunction); + } + + /// Metadata for the translations of . + @override final TranslationMetadata $meta; + + /// Access flat map + @override dynamic operator[](String key) => $meta.getTranslation(key); + + late final TranslationsFa _root = this; // ignore: unused_field + + // Translations + @override late final _TranslationsAboutScreenFa AboutScreen = _TranslationsAboutScreenFa._(_root); + @override late final _TranslationsAddProfileByImportFromFileScreenFa AddProfileByImportFromFileScreen = _TranslationsAddProfileByImportFromFileScreenFa._(_root); + @override late final _TranslationsAddProfileByLinkOrContentScreenFa AddProfileByLinkOrContentScreen = _TranslationsAddProfileByLinkOrContentScreenFa._(_root); + @override late final _TranslationsAddProfileByScanQrcodeScanScreenFa AddProfileByScanQrcodeScanScreen = _TranslationsAddProfileByScanQrcodeScanScreenFa._(_root); + @override late final _TranslationsBackupAndSyncLanSyncScreenFa BackupAndSyncLanSyncScreen = _TranslationsBackupAndSyncLanSyncScreenFa._(_root); + @override late final _TranslationsBackupAndSyncWebdavScreenFa BackupAndSyncWebdavScreen = _TranslationsBackupAndSyncWebdavScreenFa._(_root); + @override late final _TranslationsDiversionGroupCustomEditScreenFa DiversionGroupCustomEditScreen = _TranslationsDiversionGroupCustomEditScreenFa._(_root); + @override late final _TranslationsDiversionRuleDetectScreenFa DiversionRuleDetectScreen = _TranslationsDiversionRuleDetectScreenFa._(_root); + @override late final _TranslationsDiversionRulesScreenFa DiversionRulesScreen = _TranslationsDiversionRulesScreenFa._(_root); + @override late final _TranslationsDnsSettingsScreenFa DnsSettingsScreen = _TranslationsDnsSettingsScreenFa._(_root); + @override late final _TranslationsFeedbackScreenFa FeedbackScreen = _TranslationsFeedbackScreenFa._(_root); + @override late final _TranslationsFileContentViewerScreenFa FileContentViewerScreen = _TranslationsFileContentViewerScreenFa._(_root); + @override late final _TranslationsHomeScreenFa HomeScreen = _TranslationsHomeScreenFa._(_root); + @override late final _TranslationsLaunchFailedScreenFa LaunchFailedScreen = _TranslationsLaunchFailedScreenFa._(_root); + @override late final _TranslationsMyProfilesEditScreenFa MyProfilesEditScreen = _TranslationsMyProfilesEditScreenFa._(_root); + @override late final _TranslationsMyProfilesMergeScreenFa MyProfilesMergeScreen = _TranslationsMyProfilesMergeScreenFa._(_root); + @override late final _TranslationsMyProfilesScreenFa MyProfilesScreen = _TranslationsMyProfilesScreenFa._(_root); + @override late final _TranslationsNetCheckScreenFa NetCheckScreen = _TranslationsNetCheckScreenFa._(_root); + @override late final _TranslationsNetConnectionsFilterScreenFa NetConnectionsFilterScreen = _TranslationsNetConnectionsFilterScreenFa._(_root); + @override late final _TranslationsNetConnectionsScreenFa NetConnectionsScreen = _TranslationsNetConnectionsScreenFa._(_root); + @override late final _TranslationsPerAppAndroidScreenFa PerAppAndroidScreen = _TranslationsPerAppAndroidScreenFa._(_root); + @override late final _TranslationsQrcodeScreenFa QrcodeScreen = _TranslationsQrcodeScreenFa._(_root); + @override late final _TranslationsRegionSettingsScreenFa RegionSettingsScreen = _TranslationsRegionSettingsScreenFa._(_root); + @override late final _TranslationsServerSelectScreenFa ServerSelectScreen = _TranslationsServerSelectScreenFa._(_root); + @override late final _TranslationsSettingsScreenFa SettingsScreen = _TranslationsSettingsScreenFa._(_root); + @override late final _TranslationsSpeedTestSettingsScreenFa SpeedTestSettingsScreen = _TranslationsSpeedTestSettingsScreenFa._(_root); + @override late final _TranslationsTextToQrCodeScreenFa TextToQrCodeScreen = _TranslationsTextToQrCodeScreenFa._(_root); + @override late final _TranslationsUserAgreementScreenFa UserAgreementScreen = _TranslationsUserAgreementScreenFa._(_root); + @override late final _TranslationsVersionUpdateScreenFa VersionUpdateScreen = _TranslationsVersionUpdateScreenFa._(_root); + @override late final _TranslationsCommonWidgetFa CommonWidget = _TranslationsCommonWidgetFa._(_root); + @override late final _TranslationsServerManagerFa ServerManager = _TranslationsServerManagerFa._(_root); + @override late final _TranslationsMainFa main = _TranslationsMainFa._(_root); + @override String get enable => 'فعال‌سازی'; + @override String get disable => 'غیرفعال'; + @override String get filter => 'فیلتر'; + @override String get filterMethod => 'روش فیلتر'; + @override String get include => 'شامل شود'; + @override String get exclude => 'حذف کردن'; + @override String get all => 'همه'; + @override String get prefer => 'اولویت'; + @override String get only => 'فقط'; + @override String get open => 'باز کن'; + @override String get close => 'بسته'; + @override String get quit => 'خروج'; + @override String get add => 'افزودن'; + @override String get remove => 'حذف'; + @override String get edit => 'ویرایش کنید'; + @override String get view => 'بررسی'; + @override String get more => 'بیشتر'; + @override String get addProfile => 'افزودن پروفایل'; + @override String get addSuccess => 'با‌موفقیت اضافه شد'; + @override String addSuccessThen({required Object p}) => 'پیکربندی با موفقیت ایجاد شد، لطفاً برای مشاهده به [${p}] بروید'; + @override String addFailed({required Object p}) => 'افزودن ناموفق بود:${p}'; + @override String get removeConfirm => 'آیا از حذف اطمینان دارین؟'; + @override String get tips => 'اطلاعات'; + @override String get copy => 'کپی'; + @override String get ok => 'خُب'; + @override String get cancel => 'لغو'; + @override String get feedback => 'بازخورد'; + @override String get faq => 'سوالات متداول'; + @override String get download => 'دانلود'; + @override String get loading => 'درحال بارگذاری…'; + @override String updateFailed({required Object p}) => 'به‌روزرسانی ناموفق بود:${p}'; + @override String get days => 'روز'; + @override String get hours => 'ساعت'; + @override String get minutes => 'دقیقه'; + @override String get seconds => 'دومین'; + @override String get protocol => 'پروتکل'; + @override String get search => 'جستجو'; + @override String get custom => 'سفارشی'; + @override String get connect => 'اتصال'; + @override String get disconnect => 'قطع‌ اتصال'; + @override String get connected => 'وصل شد'; + @override String get disconnected => 'قطع شد'; + @override String get connecting => 'درحال اتصال'; + @override String get connectTimeout => 'اتمام مهلت اتصال'; + @override String get timeout => 'تایم اوت'; + @override String get language => 'زبان'; + @override String get next => 'بعدی'; + @override String get done => 'انجام‌شد'; + @override String get apply => 'درخواست دادن'; + @override String get refresh => 'بارگذاری مجدد'; + @override String get retry => 'دوباره امتحان کنید؟'; + @override String get none => 'هیچ‌کدام'; + @override String get reset => 'ریست'; + @override String get submit => 'ارسال'; + @override String get account => 'نام‌کاربری'; + @override String get password => 'رمز‌عبور'; + @override String get required => 'الزامی'; + @override String get diversion => 'انحراف'; + @override String get diversionRules => 'قوانین انحراف'; + @override String get diversionRulesEnable => 'قوانین بارگیری [ISP] را فعال کنید'; + @override String get diversionCustomGroup => 'گروه انحراف سفارشی'; + @override String get diversionCustomGroupPreset => 'از پیش تنظیم شده [گروه انحراف سفارشی]'; + @override String get diversionCustomGroupPresetTips => 'توجه: موارد فعال به [گروه انحراف سفارشی] و [قوانین انحراف] اضافه/پوشش داده خواهند شد'; + @override String get diversionCustomGroupAddTips => 'توجه: ممکن است لازم باشد پس از افزودن مرتب‌سازی به‌صورت دستی آن را تنظیم کنید، در غیر این صورت انحراف تازه اضافه‌شده ممکن است اعمال نشود.'; + @override String get urlTestCustomGroup => 'گروه پروکسی سفارشی'; + @override String get rulesetEnableTips => 'راهنمایی: پس‌از ذخیره کردن لطفا به [قوانین انحراف] رفته و قوانین مربوط زا تنظیم کنید؛ درغیراین صورت اعمال نخواهند شد'; + @override String get ispUserAgentTips => '[ISP] انواع مختلف داده های اشتراک را بر اساس [UserAgent] در درخواست [HTTP] ارائه خواهد کرد.'; + @override String get ispDiversionTips => 'قوانین بارگذاری ارائه شده توسط [ISP]، اشتراک های نوع [V2Ray] از قوانین تخلیه پشتیبانی نمی کنند'; + @override String get staticIP => 'IP استاتیک'; + @override String get other => 'دیگر'; + @override String get dns => 'DNS'; + @override String get url => 'URL'; + @override String get isp => 'ISP'; + @override String get tls => 'TLS'; + @override String get userAgent => 'UserAgent'; + @override String get urlInvalid => 'URL نامعتبر'; + @override String get outboundActionCurrentSelected => 'فعلی انتخاب شده'; + @override String get outboundActionUrltest => 'انتخاب خودکار'; + @override String get outboundActionDirect => 'مستقیم'; + @override String get outboundActionBlock => 'مسدود'; + @override String get routeFinal => 'نهایی'; + @override String get rulesetGeoSite => 'GeoSite'; + @override String get rulesetGeoIp => 'GeoIP'; + @override String get rulesetAcl => 'ACL'; + @override String get iCloud => 'iCloud'; + @override String get appleTV => 'Apple TV'; + @override String get webdav => 'Webdav'; + @override String get setting => 'تنظیمات'; + @override String get protocolSniff => 'تشخیص پروتکل'; + @override String get protocolSniffOverrideDestination => 'نام دامنه شناسایی شده آدرس هدف اتصال را پوشش می دهد'; + @override String get remark => 'ملاحضات'; + @override String get remarkCannotEmpty => 'ملاحظات نمی‌تواند خالی باشد'; + @override String get remarkTooLong => 'ملاحظات تا ۳۲ حرف'; + @override String get remarkExist => 'ملاحظات از‌قبل وجود دارد، لطفا از نام دیگری استفاده کنید'; + @override String get domainSuffix => 'پسوند دامنه'; + @override String get domain => 'دامنه'; + @override String get domainKeyword => 'کلید‌واژه دامنه'; + @override String get domainRegex => 'عبارات باقاعده ی دامنه (Regex)'; + @override String get ip => 'IP'; + @override String get port => 'پورت'; + @override String get appPackage => 'نام بسته‌ی برنامه'; + @override String get processName => 'نام اجرایی پروسه'; + @override String get processPath => 'مسیر پروسه'; + @override String get systemProxy => 'پروکسی سیستم'; + @override String get netInterfaces => 'رابط شبکه'; + @override String get netSpeed => 'سرعت'; + @override String get website => 'وبسایت'; + @override String get rule => 'قانون'; + @override String get global => 'عمومی'; + @override String get qrcode => 'کد QR'; + @override String get scanQrcode => 'اسکن QRکد'; + @override String get scanResult => 'نتایج اسکن'; + @override String get backupAndSync => 'پشتیبان‌گیری و همگام‌سازی'; + @override String get importAndExport => 'وارد‌کردن و خروجی‌گرفتن'; + @override String get import => 'وارد‌کردن'; + @override String get export => 'خروجی‌گرفتن'; + @override String get send => 'ارسال کنید'; + @override String get receive => 'تصاحب'; + @override String sendOrReceiveNotMatch({required Object p}) => 'لطفا از [${p}] استفاده کنید'; + @override String get sendConfirm => 'ارسال را تایید کرد؟'; + @override String get termOfUse => 'شرایط استفاده'; + @override String get privacyPolicy => 'سیاست حریم خصوصی'; + @override String get about => 'درباره'; + @override String get name => 'نام'; + @override String get version => 'نسخه'; + @override String get notice => 'اطلاعیه'; + @override String get sort => 'مرتب‌سازی'; + @override String get novice => 'حالت مبتدی'; + @override String get recommended => 'پیشنهادی'; + @override String innerError({required Object p}) => 'خطای داخلی: ${p}'; + @override String get logicOperation => 'عملیات منطقی'; + @override String get share => 'اشتراک گذاری'; + @override String get candidateWord => 'کلمات نامزد'; + @override String get keywordOrRegx => 'کلمات کلیدی / معمولی'; + @override String get importFromClipboard => 'افزودن از کلیپ‌برد'; + @override String get exportToClipboard => 'صادرات به کلیپ بورد'; + @override String get server => 'سرور'; + @override String get appleTVConnectTurnOfprivateDirect => 'لطفاً ابتدا [اتصال مستقیم شبکه خصوصی] را فعال کنید'; + @override String targetConnectFailed({required Object p}) => 'اتصال به [${p}] ناموفق بود، لطفاً مطمئن شوید که دستگاه در همان LAN است و [اتصال مستقیم شبکه خصوصی] را فعال کنید.'; + @override String get appleTVSync => 'همگام سازی پیکربندی هسته فعلی با Apple TV - Karing'; + @override String get appleTVSyncDone => 'همگام سازی کامل شد، لطفاً برای باز کردن/راه اندازی مجدد اتصال به Apple TV - Karing بروید'; + @override String get appleTVRemoveCoreConfig => 'حذف Apple TV - Karing Core Configuration'; + @override String get appleTVRemoveCoreConfigDone => 'Apple TV - نمایه اصلی کارینگ حذف شد'; + @override String get appleTVUrlInvalid => 'URL نامعتبر است، لطفاً Apple TV - Karing را باز کنید، کد QR نمایش داده شده توسط Karing را اسکن کنید'; + @override String get remoteProfileEditConfirm => 'پس از به روز رسانی تنظیمات، تغییرات گره بازیابی می شوند آیا می خواهید ادامه دهید؟'; + @override String invalidFileType({required Object p}) => 'نوع فایل نامعتبر:${p}'; + @override String get mustBeValidHttpsURL => 'باید یک URL معتبر https باشد'; + @override String fileNotExistReinstall({required Object p}) => 'فایل [${p}] وجود ندارد، لطفا دوباره نصب کنید'; + @override String get latencyTest => 'بررسی تاخیر'; + @override String get latencyTestResolveIP => 'در طی تشخیص دستی، IP صادرات نیز تجزیه و تحلیل می شود.'; + @override String get uwpExemption => 'معافیت جداسازی شبکه UWP'; + @override String get removeBannerAds => 'تبلیغات را حذف کنید'; + @override String get removeBannerAdsByReward => 'چند ثانیه تبلیغات را تماشا کنید و 7 روز بدون تبلیغات پاداش خواهید گرفت'; + @override String get removeBannerAdsByRewardDone => 'یک پاداش 7 روزه بدون آگهی دریافت کرد'; + @override Map get locales => { + 'en': 'English', + 'zh-CN': '简体中文', + 'ar': 'عربي', + 'ru': 'Русский', + 'fa': 'فارسی', + }; +} + +// Path: AboutScreen +class _TranslationsAboutScreenFa implements TranslationsAboutScreenEn { + _TranslationsAboutScreenFa._(this._root); + + final TranslationsFa _root; // ignore: unused_field + + // Translations + @override String get installRefer => 'مرجع نصب'; + @override String get versionChannel => 'کانال به‌روزرسانی خودکار'; + @override String get disableUAReport => 'خاموش کردن گزارش اطلاعات عملکرد'; + @override String get disableUAReportTip => 'گزارش‌دهی داده‌های رفتاری به ما کمک می‌کند تا نسخه‌های پایین‌تر از نسخه اصلی را بهبود بخشیم، همه گزارش‌های داده را به‌طور خودکار خاموش می‌کند (به‌جز [فعال‌سازی برنامه]).'; + @override String get devOptions => 'تنظیمات توسعه‌دهندگان'; + @override String get enableDebugLog => 'فعال‌سازی گزارش اشکال‌زدایی'; + @override String get viewFilsContent => 'مشاهده فایل‌ها'; + @override String get enablePprof => 'فعال‌سازی pprof'; + @override String get pprofPanel => 'پنل pprof'; + @override String get openDir => 'بازکردن دایرکتوری فایل'; + @override String get useOriginalSBProfile => 'استفاده از پروفایل اصلی سینگ‌باکس'; +} + +// Path: AddProfileByImportFromFileScreen +class _TranslationsAddProfileByImportFromFileScreenFa implements TranslationsAddProfileByImportFromFileScreenEn { + _TranslationsAddProfileByImportFromFileScreenFa._(this._root); + + final TranslationsFa _root; // ignore: unused_field + + // Translations + @override String get title => 'وارد‌کردن فایل پروفایل'; + @override String get chooseFile => 'انتخاب فایل'; + @override String get configExist => 'پروفایل از‌قبل وجود دارد، لطفا آن را به‌طور مکرر اضافه نکنید'; +} + +// Path: AddProfileByLinkOrContentScreen +class _TranslationsAddProfileByLinkOrContentScreenFa implements TranslationsAddProfileByLinkOrContentScreenEn { + _TranslationsAddProfileByLinkOrContentScreenFa._(this._root); + + final TranslationsFa _root; // ignore: unused_field + + // Translations + @override String get title => 'افزودن لینک پروفایل'; + @override String get updateTimerInterval => 'فاصله‌ی به‌روزرسانی'; + @override String get updateTimerIntervalTips => 'حداقل: 5 متر'; + @override String get profileLinkContent => 'لینک/محتوای پروفایل'; + @override String get profileLinkContentHit => 'لینک/محتوای پروفایل [الزامی] (پشتیبانی از کلش، V2ray(پشتیبانی به‌صورت دسته‌ای)، لینک‌های پروفایل فرعی)، استش، کارینگ، سینگ‌باکس، شدوساکس، لینک‌های پروفایل فرعی)'; + @override String get subscriptionCannotEmpty => 'لینک پروفایل نمی‌تواند خالی باشد'; + @override String get configExist => 'پروفایل از‌قبل وجود دارد، لطفا آن را به‌طور مکرر اضافه نکنید'; + @override String get invalidUrl => 'لینک پروفایل خیلی طولانی است'; + @override String addFailedFormatException({required Object p}) => 'فرمت اشتباه است، لطفا آن را اصلاح کرده و مجدد اضافه کنید:${p}'; + @override String addFailedThenDownloadAndImport({required Object p}) => 'افزودن نشد: ${p}، لطفاً [UserAgent] را تغییر دهید و دوباره امتحان کنید، یا از مرورگر خود دستگاه برای باز کردن پیوند پیکربندی و وارد کردن فایل پیکربندی دانلود شده توسط مرورگر به این برنامه استفاده کنید.'; + @override String addFailedHandshakeException({required Object p}) => 'اضافه کردن: ${p} ناموفق بود، لطفاً عامل را باز کنید یا گره عامل فعلی را تغییر دهید و دوباره امتحان کنید'; +} + +// Path: AddProfileByScanQrcodeScanScreen +class _TranslationsAddProfileByScanQrcodeScanScreenFa implements TranslationsAddProfileByScanQrcodeScanScreenEn { + _TranslationsAddProfileByScanQrcodeScanScreenFa._(this._root); + + final TranslationsFa _root; // ignore: unused_field + + // Translations + @override String get copy => 'کپی‌کردن لینک'; + @override String get open => 'بازکردن لینک'; + @override String get requestCameraPermission => 'لطفا مجوز دسترسی دوربین را فعال کنید'; + @override String get requestScreenAccess => 'لطفا به تنظیمات دستگاه - حریم‌خصوصی و امنیت - ظبط صفحه بروین تا مجوز‌های این نرم‌افزار را اضافه کنید'; + @override String get screenshot => 'اسکرین‌شات'; + @override String get scanFromImage => 'اسکن از عکس'; + @override String get scanNoResult => 'تجزیه عکس ناموفق بود، لطفا مطمعن شوید اسکرین‌شات یک کدQR معتبر است'; + @override String get scanEmptyResult => 'نتیجه اسکن خالی است'; + @override String scanException({required Object p}) => 'تجزیه عکس ناموفق بود، لطفا مطمعن شوید اسکرین‌شات یک کدQR معتبر است: ${p}'; +} + +// Path: BackupAndSyncLanSyncScreen +class _TranslationsBackupAndSyncLanSyncScreenFa implements TranslationsBackupAndSyncLanSyncScreenEn { + _TranslationsBackupAndSyncLanSyncScreenFa._(this._root); + + final TranslationsFa _root; // ignore: unused_field + + // Translations + @override String get title => 'LAN Sync'; + @override String get lanSyncNotQuitTips => 'قبل از تکمیل همگام‌سازی از این قسمت خارج نشوید'; +} + +// Path: BackupAndSyncWebdavScreen +class _TranslationsBackupAndSyncWebdavScreenFa implements TranslationsBackupAndSyncWebdavScreenEn { + _TranslationsBackupAndSyncWebdavScreenFa._(this._root); + + final TranslationsFa _root; // ignore: unused_field + + // Translations + @override String get webdavServerUrl => 'آدرس URL سرور'; + @override String get webdavRequired => 'نمی‌تواند خالی باشد'; + @override String get webdavLoginFailed => 'ورود ناموفق بود:'; + @override String get webdavListFailed => 'دریافت لیست فایل ناموفق بود:'; +} + +// Path: DiversionGroupCustomEditScreen +class _TranslationsDiversionGroupCustomEditScreenFa implements TranslationsDiversionGroupCustomEditScreenEn { + _TranslationsDiversionGroupCustomEditScreenFa._(this._root); + + final TranslationsFa _root; // ignore: unused_field + + // Translations + @override String invalidDomain({required Object p}) => 'نامعتبر [Domain]:${p}'; + @override String invalidIpCidr({required Object p}) => 'نامعتبر [IP Cidr]:${p}'; + @override String invalidPort({required Object p}) => 'نامعتبر [Port]:${p}'; + @override String invalidRuleSet({required Object p}) => 'نامعتبر [Rule Set]:${p} باید URL یک URL معتبر https باشد و یک فایل دودویی(binary) با پسوند فایل .srs/.json باشد'; + @override String invalidRuleSetBuildIn({required Object p}) => 'نامعتبر [Rule Set(build-in)]:${p} نامعتبر است، قالب geosite:xxx یا geoip:xxx یا acl:xxx است و xxx باید یک نام قانون معتبر باشد'; + @override String get setDiversionRule => 'راهنمایی: پس‌از ذخیره کردن لطفا به [قوانین انحراف] رفته و قوانین مربوط زا تنظیم کنید؛ درغیراین صورت اعمال نخواهند شد'; +} + +// Path: DiversionRuleDetectScreen +class _TranslationsDiversionRuleDetectScreenFa implements TranslationsDiversionRuleDetectScreenEn { + _TranslationsDiversionRuleDetectScreenFa._(this._root); + + final TranslationsFa _root; // ignore: unused_field + + // Translations + @override String get title => 'کشف قانون انحراف'; + @override String get detect => 'کشف'; + @override String get rule => 'قانون:'; + @override String get outbound => 'سرور پروکسی:'; +} + +// Path: DiversionRulesScreen +class _TranslationsDiversionRulesScreenFa implements TranslationsDiversionRulesScreenEn { + _TranslationsDiversionRulesScreenFa._(this._root); + + final TranslationsFa _root; // ignore: unused_field + + // Translations + @override String get diversionRulesMatchTips => 'نکته: سعی کنید قوانین را از بالا به پایین مطابقت دهید، از [نهایی] استفاده کنید.'; +} + +// Path: DnsSettingsScreen +class _TranslationsDnsSettingsScreenFa implements TranslationsDnsSettingsScreenEn { + _TranslationsDnsSettingsScreenFa._(this._root); + + final TranslationsFa _root; // ignore: unused_field + + // Translations + @override String get ispCanNotEmpty => 'ISP نمی‌تواند خالی باشد'; + @override String get urlCanNotEmpty => 'URL نمی‌تواند خالی باشد'; + @override String error({required Object p}) => 'نوع پشتیبانی نشده:${p}'; + @override String get dnsDesc => 'ستون اول داده‌های تأخیر، تأخیر ارتباط مستقیم است؛\nستون دوم: روشن کردن [[ترافیک پروکسی] برای حل و فصل DNS از طریق سرور پراکسی]: داده‌های تأخیر، تأخیر درخواست ارسال شده از طریق سرور پراکسی فعلی است [[ترافیک پروکسی] روشن نیست، از طریق سرور پروکسی DNS را حل می‌کند]: داده‌های تأخیر تأخیر درخواست اتصال مستقیم است'; +} + +// Path: FeedbackScreen +class _TranslationsFeedbackScreenFa implements TranslationsFeedbackScreenEn { + _TranslationsFeedbackScreenFa._(this._root); + + final TranslationsFa _root; // ignore: unused_field + + // Translations + @override String get content => 'محتوای بازخورد'; + @override String get contentHit => 'الزامی، تا 500 حرف'; + @override String get contentCannotEmpty => 'محتوای بازخورد نمی‌تواند خالی باشد'; +} + +// Path: FileContentViewerScreen +class _TranslationsFileContentViewerScreenFa implements TranslationsFileContentViewerScreenEn { + _TranslationsFileContentViewerScreenFa._(this._root); + + final TranslationsFa _root; // ignore: unused_field + + // Translations + @override String get title => 'نمایش دهنده محتوای فایل'; + @override String get chooseFile => 'انتخاب فایل'; + @override String get clearFileContent => 'آیا از پاکسازی محتوای فایل اطمینان دارید؟'; + @override String get clearFileContentTips => 'آیا از پاکسازی محتوای فایل پروفایل اطمینان دارید؟ پاکسازی محتوای فایل پروفایل ممکن است باعث از دست رفتن داده یا عملیات غیرعادی نرم‌افزار شود؛ لطفا با احتیاط عمل کنید.'; +} + +// Path: HomeScreen +class _TranslationsHomeScreenFa implements TranslationsHomeScreenEn { + _TranslationsHomeScreenFa._(this._root); + + final TranslationsFa _root; // ignore: unused_field + + // Translations + @override String get toSelectServer => 'لطفا یک سرور انتخاب کنید'; + @override String get invalidServer => 'نامعتبر است، لطفا مجدد انتخاب کنید'; + @override String get disabledServer => 'غیرفعال است، لطفا مجدد انتخاب کنید'; + @override String get expiredServer => 'هیچ سروری در دسترس نیست: ممکن است پیکربندی قدیمی یا غیرفعال باشد'; + @override String systemProxyTips({required Object sp, required Object hp}) => 'socks:${sp},http(s):${hp}'; + @override String get trafficTotal => 'کل ترافیک'; + @override String get trafficProxy => 'ترافیک پروکسی'; + @override String get myLinkEmpty => 'لطفا قبل‌از استفاده [لینک میان‌بر] را راه‌اندازی کنید'; + @override String get deviceNoSpace => 'فضای خالی کافی ندارید'; + @override String tooMuchServers({required Object p, required Object p1}) => 'تعداد زیادی سرور پروکسی [${p}>${p1}] وجود دارد و ممکن است به دلیل محدودیت حافظه سیستم، اتصال امکان پذیر نباشد.'; +} + +// Path: LaunchFailedScreen +class _TranslationsLaunchFailedScreenFa implements TranslationsLaunchFailedScreenEn { + _TranslationsLaunchFailedScreenFa._(this._root); + + final TranslationsFa _root; // ignore: unused_field + + // Translations + @override String get invalidProcess => 'اجرای نرم‌افزار ناموفق بود [نام‌ اجرایی پروسه نامعتبر]، لطفا مجدد نرم‌افزار را در دایرکتوری دیگری نصب کنید'; + @override String get invalidProfile => 'اجرای نرم‌افزار ناموفق بود [دسترسی به پروفایل ناموفق بود]، لطفا مجدد نرم افزار را نصب کنید'; + @override String get invalidVersion => 'اجرای نرم‌افزار ناموفق بود [ورژن نامعتبر]، لطفا مجدد نرم‌افزار را نصب کنید'; + @override String get systemVersionLow => 'راه اندازی برنامه ناموفق بود [نسخه سیستم خیلی کم است]'; + @override String get invalidInstallPath => 'مسیر نصب نامعتبر است، لطفا مجدد در مسیر معتبر نصب کنید'; +} + +// Path: MyProfilesEditScreen +class _TranslationsMyProfilesEditScreenFa implements TranslationsMyProfilesEditScreenEn { + _TranslationsMyProfilesEditScreenFa._(this._root); + + final TranslationsFa _root; // ignore: unused_field + + // Translations + @override String get title => 'ویرایش پروفایل'; + @override String get urlExist => 'آدرس URL از‌قبل وجود دارد، لطفا از URL دیگری استفاده کنید'; + @override String get updateTimerInterval => 'فاصله‌ی به‌روزرسانی'; + @override String get updateTimerIntervalTips => 'حداقل: 5 متر'; + @override String get reloadAfterProfileUpdate => 'بارگذاری مجدد پس‌از به‌روزرسانی پروفایل'; + @override String get testLatencyAfterProfileUpdate => 'شروع تست تاخیر پس‌از به‌روزرسانی خودکار پروفایل'; + @override String get testLatencyAfterProfileUpdateTips => 'وی‌پی‌ان باید روشن و [بارگذاری مجدد پس‌از به‌روزرسانی پروفایل] فعال باشد'; + @override String get testLatencyAutoRemove => 'خودکار سرورهای ناموفق در تست تاخیر را حذف کن'; + @override String get testLatencyAutoRemoveTips => 'تا سه بار امتحان کنید'; +} + +// Path: MyProfilesMergeScreen +class _TranslationsMyProfilesMergeScreenFa implements TranslationsMyProfilesMergeScreenEn { + _TranslationsMyProfilesMergeScreenFa._(this._root); + + final TranslationsFa _root; // ignore: unused_field + + // Translations + @override String get profilesMerge => 'ادغام پروفایل‌ها'; + @override String get profilesMergeTarget => 'پروفایل هدف'; + @override String get profilesMergeSource => 'پروفایل مرجع'; + @override String get profilesMergeTips => 'راهنمایی: انحراف پروفایل مرجع حذف می‌شود'; +} + +// Path: MyProfilesScreen +class _TranslationsMyProfilesScreenFa implements TranslationsMyProfilesScreenEn { + _TranslationsMyProfilesScreenFa._(this._root); + + final TranslationsFa _root; // ignore: unused_field + + // Translations + @override String get title => 'پروفایل‌ها'; + @override String get atLeastOneEnable => 'نمی‌تواند غیرغعال شود، لطفا حداقل یک پروفایل را فعال نگه دارید'; +} + +// Path: NetCheckScreen +class _TranslationsNetCheckScreenFa implements TranslationsNetCheckScreenEn { + _TranslationsNetCheckScreenFa._(this._root); + + final TranslationsFa _root; // ignore: unused_field + + // Translations + @override String get title => 'بررسی شبکه'; + @override String get warn => 'توجه: به دلیل تأثیر محیط شبکه و قوانین انحراف، نتایج آزمون کاملاً معادل نتایج واقعی نیست.'; + @override String get check => 'بررسی'; + @override String get invalidDomain => 'نام دامنه نامعتبر'; + @override String get connectivity => 'اتصال شبکه'; + @override String connectivityTestIpv4AllFailed({required Object p}) => 'تست اتصال Ipv4 همه‌ی [${p}] ناموفق بودند'; + @override String get connectivityTestIpv4Ok => 'اتصال Ipv4 موفق بود'; + @override String connectivityTestIpv6AllFailed({required Object p}) => 'تست اتصال Ipv6 همه‌ی [${p}] ناموفق بودند، شاید شبکه شما از Ipv6 پشتیبانی نکند'; + @override String get connectivityTestIpv6Ok => 'اتصال Ipv6 موفق بود'; + @override String get connectivityTestOk => 'شبکه به اینترنت متصل است'; + @override String get connectivityTestFailed => 'شبکه هنوز به اینترنت متصل نشده'; + @override String get remoteRulesetsDownloadOk => 'همه با موفقیت دانلود شدند'; + @override String get remoteRulesetsDownloadNotOk => 'دانلود شد یا ناموفق بود'; + @override String get outbound => 'سرور پروکسی'; + @override String outboundOk({required Object p}) => '[${p}] اتصال موفق بود'; + @override String outboundFailed({required Object p1, required Object p2}) => '[${p1}] اتصال ناموفق \nارور:[${p2}]'; + @override String get dnsServer => 'سرور دی‌ان‌اس'; + @override String dnsOk({required Object p1, required Object p2, required Object p3, required Object p4}) => '[${p1}]DNS query succeeded\nDNS Rule: درخواست دی‌ان‌اس موفق بود\nقانون دی‌ان‌اس: [${p2}]\nتاخیر: [${p3} ms]\nآدرس [${p4}]'; + @override String dnsFailed({required Object p1, required Object p2, required Object p3}) => '[${p1}]جستجوی DNS موفق بود\nقانون DNS: [${p2}]\nخطا:[${p3}]'; + @override String get host => 'اتصال HTTP'; + @override String hostConnection({required Object p1, required Object p2, required Object p3}) => '[${p1}]\nقانون انحراف: [${p2}]\nسرور پروکسی: [${p3}]'; + @override String get hostConnectionOk => 'اتصال موفق شد'; + @override String hostConnectionFailed({required Object p}) => 'ارتباط ناموفق بود:[${p}]'; +} + +// Path: NetConnectionsFilterScreen +class _TranslationsNetConnectionsFilterScreenFa implements TranslationsNetConnectionsFilterScreenEn { + _TranslationsNetConnectionsFilterScreenFa._(this._root); + + final TranslationsFa _root; // ignore: unused_field + + // Translations + @override String get title => 'فیلتر اتصال‌ها'; + @override String get hostIp => 'دامنه/آی‌پی'; + @override String get app => 'نرم‌افزار'; + @override String get rule => 'قانون'; + @override String get chain => 'Outbound'; +} + +// Path: NetConnectionsScreen +class _TranslationsNetConnectionsScreenFa implements TranslationsNetConnectionsScreenEn { + _TranslationsNetConnectionsScreenFa._(this._root); + + final TranslationsFa _root; // ignore: unused_field + + // Translations + @override String get title => 'اتصال‌ها'; + @override String get copyAsCSV => 'در فرمت CAV کپی شد'; + @override String get selectType => 'انتخاب نوع انحراف'; +} + +// Path: PerAppAndroidScreen +class _TranslationsPerAppAndroidScreenFa implements TranslationsPerAppAndroidScreenEn { + _TranslationsPerAppAndroidScreenFa._(this._root); + + final TranslationsFa _root; // ignore: unused_field + + // Translations + @override String get title => 'پروکسی به‌تفکیک برنامه'; + @override String get whiteListMode => 'حالت لیست سفید'; + @override String get whiteListModeTip => 'وقتی فعال باشد: فقط برنامه‌هایی که انتخاب شده‌اند پروکسی می‌شوند؛ وقتی فعال نباشد: فقط برنامه‌هایی که انتخاب نشده‌اند پروکسی می‌شوند'; + @override String get hideSystemApp => 'برنامه های سیستم را مخفی کنید'; + @override String get hideAppIcon => 'پنهان کردن نماد برنامه'; + @override String get enableAppQueryPermission => 'مجوز [درخواست لیست نرم‌افزار] را روشن کنید'; +} + +// Path: QrcodeScreen +class _TranslationsQrcodeScreenFa implements TranslationsQrcodeScreenEn { + _TranslationsQrcodeScreenFa._(this._root); + + final TranslationsFa _root; // ignore: unused_field + + // Translations + @override String get tooLong => 'متن برای نمایش خیلی طولانی است'; + @override String get copy => 'کپی‌کردن لینک'; + @override String get open => 'بازکردن لینک'; + @override String get share => 'اشتراک لینک'; + @override String get shareImage => 'اشتراک کدQR'; +} + +// Path: RegionSettingsScreen +class _TranslationsRegionSettingsScreenFa implements TranslationsRegionSettingsScreenEn { + _TranslationsRegionSettingsScreenFa._(this._root); + + final TranslationsFa _root; // ignore: unused_field + + // Translations + @override String get title => 'کشور یا منطقه'; + @override String get Regions => 'راهنمایی: لطفا کشور یا منطقه فعلی خود را انتخاب کنید درغیراین‌صورت ممکن‌است باعث مشکلات انحراف شبکه شود'; +} + +// Path: ServerSelectScreen +class _TranslationsServerSelectScreenFa implements TranslationsServerSelectScreenEn { + _TranslationsServerSelectScreenFa._(this._root); + + final TranslationsFa _root; // ignore: unused_field + + // Translations + @override String get title => 'انتخاب سرور'; + @override String get autoSelectServer => 'خودکار سرور با کمترین تاخیر را انتخاب کن'; + @override String get recentUse => 'اخیرا استفاده‌شده'; + @override String get myFav => 'علاقه‌مندی‌های من'; + @override String selectLocal({required Object p}) => 'سرور انتخاب شده یک آدرس محلی است و شاید به درستی عمل نکند :${p}'; + @override String get selectRequireEnableIPv6 => 'سرور انتخاب شده یک آدرس IPv6 است و نیاز به [فعال‌سازی IPv6] دارد'; + @override String get selectDisabled => 'این سرور غیرفعال شده است'; + @override String get error404 => 'تشخیص تاخیر با یک اخطار مواجه شده‌است، لطفا بررسی کنید که کانفیگی با محتویات یکسان وجود دارد یا خیر'; +} + +// Path: SettingsScreen +class _TranslationsSettingsScreenFa implements TranslationsSettingsScreenEn { + _TranslationsSettingsScreenFa._(this._root); + + final TranslationsFa _root; // ignore: unused_field + + // Translations + @override String ispFaq({required Object p}) => 'سوالات متداول[${p}]'; + @override String cleanISP({required Object p}) => 'پاک‌سازی ISP [${p}]'; + @override String get openISP => 'بازکردن لینک ISP'; + @override String get cleanISPNoParam => 'پاک‌سازی اطلاعات ISP'; + @override String get getTranffic => 'دریافت ترافیک'; + @override String get tutorial => 'آموزش'; + @override String get commonlyUsedRulesets => 'قوانین رایج'; + @override String get howToRemoveAds => 'نحوه حذف تبلیغات'; + @override String get htmlBoard => 'پنل آنلاین'; + @override String get dnsLeakDetection => 'تشخیص نشت DNS'; + @override String get speedTest => 'تست سرعت'; + @override String get downloadProfilePreferProxy => 'برای دانلود پروفایل پروکسی را ترجیح بده'; + @override String get downloadProfilePreferProxyTips => 'اگر اکنون متصل هستین، پروفایل ابتدا از پروکسی متصل دانلود می‌شود'; + @override String get rulesetDirectDownlad => 'دانلود مستقیم مجموعه قوانین'; + @override String get hideUnusedDiversionGroup => 'مخفی‌کردن گروه‌های انحراف به‌کار نرفته'; + @override String get disableISPDiversionGroup => 'قوانین انحراف ISP را غیرفعال کنید'; + @override String get portSetting => 'پورت'; + @override String get portSettingRule => 'قانون محور'; + @override String get portSettingDirectAll => 'مستقیم‌شدن همه'; + @override String get portSettingProxyAll => 'پروکسی‌شدن همه'; + @override String get portSettingControl => 'کنترل و همگام‌سازی'; + @override String get portSettingCluster => 'سرویس کلاستر'; + @override String get modifyPort => 'اصلاح پورت'; + @override String get modifyPortOccupied => 'پورت اشغال شده است لطفا از پورت دیگری استفاده کنید'; + @override String get ipStrategyTips => 'قبل‌از فعال‌سازی لطفا مطمعن شوید شبکه شما از IPv6 پشتیبانی می‌کند، وگرنه برخی ترافیک‌ها نمی‌توانند به‌صورت نرمال دردسترس باشند'; + @override String get tunAppendHttpProxy => 'پیوست دادن پروکسی HTTP به وی‌پی‌ان'; + @override String get tunAppendHttpProxyTips => 'برخی نرم‌افزار‌ها از کارت شبکه مجازی رد میشوند و مستقیم به پروکسی HTTP متصل می‌شوند'; + @override String get tlsInsecureEnable => 'رد شدن از تأیید گواهی'; + @override String get tlsFragmentEnable => 'بخش بندی TLS را فعال کنید'; + @override String get tlsFragmentSize => 'اندازه بخش TLS'; + @override String get tlsFragmentSleep => 'خواب بخش‌بندی شده TLS'; + @override String get tlsMixedCaseSNIEnable => 'TLS ترکیبی SNI را فعال کنید'; + @override String get tlsPaddingEnable => 'فعال کردن TLS Padding'; + @override String get tlsPaddingSize => 'اندازه پد TLS'; + @override String get dnsEnableRule => 'فعال‌سازی قوانین انحراف دی‌ان‌اس'; + @override String get dnsEnableFakeIp => 'فعال‌سازی آی‌پی جعلی'; + @override String get dnsEnableClientSubnet => 'ECS را فعال کنید'; + @override String get dnsEnableProxyResolveByProxy => 'دی‌ان‌اس را از [ترافیک پروکسی] سرور پروکسی عبور می‌دهد'; + @override String get dnsEnableFinalResolveByProxy => 'دی‌ان‌اس را از سرور پروکسی [نهایی] عبور می‌دهد'; + @override String get dnsTestDomain => 'تست دامنه'; + @override String get dnsTestDomainInvalid => 'دامنه نامعتبر'; + @override String get dnsTypeOutbound => 'سرور پروکسی'; + @override String get dnsTypeDirect => 'ترافیک مستقیم'; + @override String get dnsTypeProxy => 'ترافیک پروکسی'; + @override String get dnsTypeResolver => 'سرور دی‌ان‌اس'; + @override String get dnsEnableRuleTips => 'بعد از فعال‌سازی نام دامنه، سرور دی‌ان‌اس مربوط را بر اساس قوانین انحراف برای عبور انتخاب می‌کند'; + @override String get dnsEnableFakeIpTips => 'پس از فعال کردن FakeIP، اگر اتصال VPN قطع شود، ممکن است برنامه شما نیاز به راه اندازی مجدد داشته باشد [حالت TUN].'; + @override String get dnsTypeOutboundTips => 'سامانه نام دامنه (DNS) برای سرور پروکسی'; + @override String get dnsTypeDirectTips => 'سامانه نام دامنه (DNS) برای ترافیک مستقیم'; + @override String get dnsTypeProxyTips => 'سامانه نام دامنه (DNS) برای ترافیک پروکسی'; + @override String get dnsTypeResolverTips => 'سامانه نام دامنه (DNS) برای بقیه سرور دی‌ان‌اس'; + @override String get dnsTypeFinalTips => 'سامانه نام دامنه (DNS) برای بقیه ترافیک'; + @override String get dnsAutoSetServer => 'به طور خودکار سرور را راه اندازی کنید'; + @override String get dnsResetServer => 'بازنشانی سرور'; + @override String get inboundDomainResolve => 'حل نام دامنه های ورودی'; + @override String get privateDirect => 'اتصال مستقیم شبکه خصوصی'; + @override String inboundDomainResolveTips({required Object p}) => 'برخی از نام‌های دامنه بدون قوانین انحراف پیکربندی شده باید حل و فصل شوند تا بتوانند قوانین انحراف مبتنی بر IP را تحت تأثیر قرار دهند [${p}].'; + @override String get useRomoteRes => 'از منابع راه‌دور استفاده کنید'; + @override String get autoSelect => 'انتخاب خودکار'; + @override String get autoSelectServerIgnorePerProxyServer => 'سرور پروکسی [پراکسی جلو] را نادیده بگیرید'; + @override String get autoSelectServerInterval => 'بازه زمانی بررسی تاخیر'; + @override String get autoSelectServerReTestIfNetworkUpdate => 'شناسایی مجدد زمانی که شبکه تغییر می کند'; + @override String get autoSelectServerUpdateCurrentServerAfterManualUrltest => 'سرور فعلی را پس از تشخیص تأخیر دستی به روز کنید'; + @override String get autoSelectServerIntervalTips => 'هرچه فاصله تشخیص تاخیر کمتر باشد، داده های تاخیر سرور به موقع به روز می شود، اما منابع بیشتری را اشغال می کند و برق را سریعتر مصرف می کند'; + @override String get autoSelectServerFavFirst => 'اولویت استفاده از [علاقه‌مندی‌های من]'; + @override String get autoSelectServerFavFirstTips => 'اگر لیست [علاقه‌مندی‌های من] خالی نبود از سرور‌های داخل [علاقه‌مندی‌های من] استفاده کن'; + @override String get autoSelectServerFilter => 'فیلترکردن سرور‌های نامعتبر'; + @override String autoSelectServerFilterTips({required Object p}) => 'اگر بعد از فیلتر کردن هیچ سروری در دسترس نباشد، از اولین سرورهای [${p}] استفاده خواهد شد.'; + @override String get autoSelectServerLimitedNum => 'حداکثر تعداد سرور'; + @override String get autoSelectServerLimitedNumTips => 'سرورهای بیش از این تعداد فیلتر خواهند شد'; + @override String get numInvalid => 'عدد نامعتبر'; + @override String get hideInvalidServer => 'مخفی‌کردن سرور‌های نامعتبر'; + @override String get sortServer => 'مرتب‌سازی سرور'; + @override String get sortServerTips => 'مرتب‌سازی براساس تاخیر از کم به زیاد'; + @override String get selectServerHideRecommand => 'مخفی‌کردن [پیشنهادی]'; + @override String get selectServerHideRecent => '‌ مخفی‌کردن [اخیرا استفاده‌شده]'; + @override String get selectServerHideFav => 'مخفی‌کردن [علاقه‌مندی‌های من]'; + @override String get homeScreen => 'صفحه‌ خانه'; + @override String get theme => 'تِم'; + @override String get myLink => 'لینک میان‌بر'; + @override String get myLinkInvalid => 'URL نامعتبر'; + @override String get autoConnectAfterLaunch => 'اتصال خودکار پس‌از راه‌اندازی'; + @override String get hideAfterLaunch => 'پنهان کردن پنجره پس از راه اندازی'; + @override String get autoSetSystemProxy => 'تنظیم خودکار حالت پروکسی سیستم پس‌از اتصال'; + @override String get disconnectWhenQuit => 'قطع اتصال هنگام خروج از نرم‌افزار'; + @override String get allowBypass => 'به برنامه‌ها اجازه دهید VPN را دور بزنند'; + @override String get importSuccess => 'افزودن موفق بود'; + @override String get rewriteConfirm => 'این فایل کانفیگ‌های محلی موجود را بازنویسی می‌کند. آیا می‌خواهید ادامه بدین؟'; + @override String get networkShare => 'اشتراک‌گذاری شبکه'; + @override String get frontProxy => 'پروکسی جلو'; + @override String frontProxyTips({required Object p}) => 'داده-> سرور پروکسی جلویی [پراکسی سرورهای چندگانه: بالا به پایین]-> سرور پروکسی [${p}]-> سرور هدف'; + @override String get allowOtherHostsConnect => 'اجازه اتصال دیگران'; + @override String allowOtherHostsConnectTips({required Object sp, required Object hp}) => 'socks:${sp},http(s):${hp}'; + @override String get tunAutoRoute => 'Auto Route'; + @override String get tunStrictRoute => 'Strict Route'; + @override String get tunStrictRouteTips => 'اگر پس از روشن کردن اشتراک‌گذاری، دیگران نمی‌توانند به این دستگاه دسترسی داشته باشند، لطفاً این سوئیچ را خاموش کنید.'; + @override String get enableCluster => 'فعال‌سازی پروکسی Socks/Http خوشه‌ای'; + @override String get clusterAllowOtherHostsConnect => 'اجازه اتصال دیگران به خوشه'; + @override String clusterAllowOtherHostsConnectTips({required Object ip, required Object port}) => 'http://${ip}:${port}/get_proxies'; + @override String get clusterAuth => 'احراز هویت خوشه پروکسی'; + @override String get tunMode => 'حالت TUN'; + @override String get tunModeTips => 'حالت TUN تمام ترافیک سیستم را تحت کنترل خواهد گرفت [دراین حالت می‌توانید پروکسی سیستم را غیرفعال نگه‌ دارید)'; + @override String get tunModeRunAsAdmin => 'حالت TUN نیازمند مجوز مدیر سیستم می‌باشد لطفا نرم‌افزار را مجدد با حالت مدیر (administrator) راه‌اندازی کنید'; + @override String get tunStack => 'Stack'; + @override String get launchAtStartup => 'اجرا در راه‌اندازی'; + @override String get quitWhenSwitchSystemUser => 'خروج از نرم‌افزار هنگام تعویض کاربران سیستم'; + @override String get handleScheme => 'فراخوانی Scheme سیستم'; + @override String get portableMode => 'حالت قابل‌حمل'; + @override String get portableModeDisableTips => 'اگر نیاز دارین از حالت قابل‌حمل خارج شوید لطفا از [Karing] خارج شده و به‌صورت دستی پوشه [Profiles] هم مسیر با فایل [karing.exe] را حذف کنید'; + @override String get handleKaringScheme => 'رسیدگی به ندای karing://'; + @override String get handleClashScheme => 'رسیدگی به‌ ندای clash://'; + @override String get handleSingboxScheme => 'رسیدگی به ندای sing-box://'; + @override String get alwayOnVPN => 'اتصال همیشه باز'; + @override String get removeSystemVPNConfig => 'حذف پیکربندی وی‌پی‌ان سیستم'; + @override String get timeConnectOrDisconnect => 'اتصال/قطع اتصال برنامه‌ریزی شده'; + @override String get timeConnectOrDisconnectTips => 'برای اعمال شدن وی‌پی‌ان باید متصل باشد. پس‌از روشن‌شدن [خواب خودکار] غیرفعال می‌شود'; + @override String timeConnectAndDisconnectInterval({required Object p}) => 'فاصله اتصال/قطع اتصال نمی تواند کمتر از ${p} دقیقه باشد'; + @override String get disableFontScaler => 'غیرفعال‌سازی مقیاس‌بندی فونت(با راه‌اندازی مجدد اعمال می‌شود)'; + @override String get autoOrientation => 'چرخش صفحه را دنبال کنید'; + @override String get restartTakesEffect => 'با راه‌اندازی مجدد اعمال می‌شود'; + @override String get resetSettings => 'بازنشانی تنظیمات'; + @override String get cleanCache => 'پاک کردن حافظه پنهان'; + @override String get cleanCacheDone => 'پاکسازی کامل شد'; + @override String get appleTestFlight => 'تست‌فلایت اپل'; + @override String get appleAppStore => 'اپ‌استور اپل'; + @override String hasNewVersion({required Object p}) => 'به‌روزرسانی نسخه ${p} '; + @override String get follow => 'مارو دنبال کنید'; + @override String get contactUs => 'ارتباط باما'; + @override String get rateInApp => 'امتیاز به ما'; + @override String get rateInAppStore => 'به ما در اپ‌استور امتیاز بدین'; +} + +// Path: SpeedTestSettingsScreen +class _TranslationsSpeedTestSettingsScreenFa implements TranslationsSpeedTestSettingsScreenEn { + _TranslationsSpeedTestSettingsScreenFa._(this._root); + + final TranslationsFa _root; // ignore: unused_field + + // Translations + @override String get title => 'URL تست سرعت'; +} + +// Path: TextToQrCodeScreen +class _TranslationsTextToQrCodeScreenFa implements TranslationsTextToQrCodeScreenEn { + _TranslationsTextToQrCodeScreenFa._(this._root); + + final TranslationsFa _root; // ignore: unused_field + + // Translations + @override String get title => 'متن به کد QR'; + @override String get convert => 'تبدیل'; +} + +// Path: UserAgreementScreen +class _TranslationsUserAgreementScreenFa implements TranslationsUserAgreementScreenEn { + _TranslationsUserAgreementScreenFa._(this._root); + + final TranslationsFa _root; // ignore: unused_field + + // Translations + @override String get privacyFirst => 'حریم‌خصوصی شما اولویت دارد'; + @override String get agreeAndContinue => 'پذیرفتن و ادامه'; +} + +// Path: VersionUpdateScreen +class _TranslationsVersionUpdateScreenFa implements TranslationsVersionUpdateScreenEn { + _TranslationsVersionUpdateScreenFa._(this._root); + + final TranslationsFa _root; // ignore: unused_field + + // Translations + @override String versionReady({required Object p}) => 'نسخه جدید [${p}] آماده است'; + @override String get update => 'راه‌اندازی مجدد برای به‌روزرسانی'; + @override String get cancel => 'الان‌ نه'; +} + +// Path: CommonWidget +class _TranslationsCommonWidgetFa implements TranslationsCommonWidgetEn { + _TranslationsCommonWidgetFa._(this._root); + + final TranslationsFa _root; // ignore: unused_field + + // Translations + @override String get diableAlwayOnVPN => 'اگر [وی‌پی‌ان همیشه روشن] روشن است لطفا [وی‌پی‌ان همیشه روشن] را خاموش کنید و مجدد برای اتصال تلاش کنید'; + @override String get resetPort => 'لطفاً پورت را به پورت موجود دیگری تغییر دهید یا برنامه ای را که پورت را اشغال می کند ببندید.'; +} + +// Path: ServerManager +class _TranslationsServerManagerFa implements TranslationsServerManagerEn { + _TranslationsServerManagerFa._(this._root); + + final TranslationsFa _root; // ignore: unused_field + + // Translations + @override String get noServerAvaliable => 'هیچ سروری در دسترس نیست، لطفاً مطمئن شوید که پیوند پیکربندی یا فایل پیکربندی معتبر است، اگر پیکربندی شما از GitHub آمده است، لطفاً آدرس پیوند را از دکمه [Raw] در صفحه دریافت کنید'; + @override String get filePathCannotEmpty => 'مسیر فایل نمی‌تواند خالی باشد'; + @override String fileNotExist({required Object p}) => 'فایل وجود ندارد:${p}'; + @override String get urlCannotEmpty => 'لینک نمی‌تواند خالی باشد'; + @override String get invalidUrl => 'لینک پروفایل نامعتبر است'; + @override String get parseFailed => 'تجزیه پروفایل انجام نشد'; +} + +// Path: main +class _TranslationsMainFa implements TranslationsMainEn { + _TranslationsMainFa._(this._root); + + final TranslationsFa _root; // ignore: unused_field + + // Translations + @override late final _TranslationsMainTrayFa tray = _TranslationsMainTrayFa._(_root); +} + +// Path: main.tray +class _TranslationsMainTrayFa implements TranslationsMainTrayEn { + _TranslationsMainTrayFa._(this._root); + + final TranslationsFa _root; // ignore: unused_field + + // Translations + @override String get menuOpen => ' بازکردن '; + @override String get menuExit => ' بستن '; +} + +/// Flat map(s) containing all translations. +/// Only for edge cases! For simple maps, use the map function of this library. +extension on TranslationsFa { + dynamic _flatMapFunction(String path) { + switch (path) { + case 'AboutScreen.installRefer': return 'مرجع نصب'; + case 'AboutScreen.versionChannel': return 'کانال به‌روزرسانی خودکار'; + case 'AboutScreen.disableUAReport': return 'خاموش کردن گزارش اطلاعات عملکرد'; + case 'AboutScreen.disableUAReportTip': return 'گزارش‌دهی داده‌های رفتاری به ما کمک می‌کند تا نسخه‌های پایین‌تر از نسخه اصلی را بهبود بخشیم، همه گزارش‌های داده را به‌طور خودکار خاموش می‌کند (به‌جز [فعال‌سازی برنامه]).'; + case 'AboutScreen.devOptions': return 'تنظیمات توسعه‌دهندگان'; + case 'AboutScreen.enableDebugLog': return 'فعال‌سازی گزارش اشکال‌زدایی'; + case 'AboutScreen.viewFilsContent': return 'مشاهده فایل‌ها'; + case 'AboutScreen.enablePprof': return 'فعال‌سازی pprof'; + case 'AboutScreen.pprofPanel': return 'پنل pprof'; + case 'AboutScreen.openDir': return 'بازکردن دایرکتوری فایل'; + case 'AboutScreen.useOriginalSBProfile': return 'استفاده از پروفایل اصلی سینگ‌باکس'; + case 'AddProfileByImportFromFileScreen.title': return 'وارد‌کردن فایل پروفایل'; + case 'AddProfileByImportFromFileScreen.chooseFile': return 'انتخاب فایل'; + case 'AddProfileByImportFromFileScreen.configExist': return 'پروفایل از‌قبل وجود دارد، لطفا آن را به‌طور مکرر اضافه نکنید'; + case 'AddProfileByLinkOrContentScreen.title': return 'افزودن لینک پروفایل'; + case 'AddProfileByLinkOrContentScreen.updateTimerInterval': return 'فاصله‌ی به‌روزرسانی'; + case 'AddProfileByLinkOrContentScreen.updateTimerIntervalTips': return 'حداقل: 5 متر'; + case 'AddProfileByLinkOrContentScreen.profileLinkContent': return 'لینک/محتوای پروفایل'; + case 'AddProfileByLinkOrContentScreen.profileLinkContentHit': return 'لینک/محتوای پروفایل [الزامی] (پشتیبانی از کلش، V2ray(پشتیبانی به‌صورت دسته‌ای)، لینک‌های پروفایل فرعی)، استش، کارینگ، سینگ‌باکس، شدوساکس، لینک‌های پروفایل فرعی)'; + case 'AddProfileByLinkOrContentScreen.subscriptionCannotEmpty': return 'لینک پروفایل نمی‌تواند خالی باشد'; + case 'AddProfileByLinkOrContentScreen.configExist': return 'پروفایل از‌قبل وجود دارد، لطفا آن را به‌طور مکرر اضافه نکنید'; + case 'AddProfileByLinkOrContentScreen.invalidUrl': return 'لینک پروفایل خیلی طولانی است'; + case 'AddProfileByLinkOrContentScreen.addFailedFormatException': return ({required Object p}) => 'فرمت اشتباه است، لطفا آن را اصلاح کرده و مجدد اضافه کنید:${p}'; + case 'AddProfileByLinkOrContentScreen.addFailedThenDownloadAndImport': return ({required Object p}) => 'افزودن نشد: ${p}، لطفاً [UserAgent] را تغییر دهید و دوباره امتحان کنید، یا از مرورگر خود دستگاه برای باز کردن پیوند پیکربندی و وارد کردن فایل پیکربندی دانلود شده توسط مرورگر به این برنامه استفاده کنید.'; + case 'AddProfileByLinkOrContentScreen.addFailedHandshakeException': return ({required Object p}) => 'اضافه کردن: ${p} ناموفق بود، لطفاً عامل را باز کنید یا گره عامل فعلی را تغییر دهید و دوباره امتحان کنید'; + case 'AddProfileByScanQrcodeScanScreen.copy': return 'کپی‌کردن لینک'; + case 'AddProfileByScanQrcodeScanScreen.open': return 'بازکردن لینک'; + case 'AddProfileByScanQrcodeScanScreen.requestCameraPermission': return 'لطفا مجوز دسترسی دوربین را فعال کنید'; + case 'AddProfileByScanQrcodeScanScreen.requestScreenAccess': return 'لطفا به تنظیمات دستگاه - حریم‌خصوصی و امنیت - ظبط صفحه بروین تا مجوز‌های این نرم‌افزار را اضافه کنید'; + case 'AddProfileByScanQrcodeScanScreen.screenshot': return 'اسکرین‌شات'; + case 'AddProfileByScanQrcodeScanScreen.scanFromImage': return 'اسکن از عکس'; + case 'AddProfileByScanQrcodeScanScreen.scanNoResult': return 'تجزیه عکس ناموفق بود، لطفا مطمعن شوید اسکرین‌شات یک کدQR معتبر است'; + case 'AddProfileByScanQrcodeScanScreen.scanEmptyResult': return 'نتیجه اسکن خالی است'; + case 'AddProfileByScanQrcodeScanScreen.scanException': return ({required Object p}) => 'تجزیه عکس ناموفق بود، لطفا مطمعن شوید اسکرین‌شات یک کدQR معتبر است: ${p}'; + case 'BackupAndSyncLanSyncScreen.title': return 'LAN Sync'; + case 'BackupAndSyncLanSyncScreen.lanSyncNotQuitTips': return 'قبل از تکمیل همگام‌سازی از این قسمت خارج نشوید'; + case 'BackupAndSyncWebdavScreen.webdavServerUrl': return 'آدرس URL سرور'; + case 'BackupAndSyncWebdavScreen.webdavRequired': return 'نمی‌تواند خالی باشد'; + case 'BackupAndSyncWebdavScreen.webdavLoginFailed': return 'ورود ناموفق بود:'; + case 'BackupAndSyncWebdavScreen.webdavListFailed': return 'دریافت لیست فایل ناموفق بود:'; + case 'DiversionGroupCustomEditScreen.invalidDomain': return ({required Object p}) => 'نامعتبر [Domain]:${p}'; + case 'DiversionGroupCustomEditScreen.invalidIpCidr': return ({required Object p}) => 'نامعتبر [IP Cidr]:${p}'; + case 'DiversionGroupCustomEditScreen.invalidPort': return ({required Object p}) => 'نامعتبر [Port]:${p}'; + case 'DiversionGroupCustomEditScreen.invalidRuleSet': return ({required Object p}) => 'نامعتبر [Rule Set]:${p} باید URL یک URL معتبر https باشد و یک فایل دودویی(binary) با پسوند فایل .srs/.json باشد'; + case 'DiversionGroupCustomEditScreen.invalidRuleSetBuildIn': return ({required Object p}) => 'نامعتبر [Rule Set(build-in)]:${p} نامعتبر است، قالب geosite:xxx یا geoip:xxx یا acl:xxx است و xxx باید یک نام قانون معتبر باشد'; + case 'DiversionGroupCustomEditScreen.setDiversionRule': return 'راهنمایی: پس‌از ذخیره کردن لطفا به [قوانین انحراف] رفته و قوانین مربوط زا تنظیم کنید؛ درغیراین صورت اعمال نخواهند شد'; + case 'DiversionRuleDetectScreen.title': return 'کشف قانون انحراف'; + case 'DiversionRuleDetectScreen.detect': return 'کشف'; + case 'DiversionRuleDetectScreen.rule': return 'قانون:'; + case 'DiversionRuleDetectScreen.outbound': return 'سرور پروکسی:'; + case 'DiversionRulesScreen.diversionRulesMatchTips': return 'نکته: سعی کنید قوانین را از بالا به پایین مطابقت دهید، از [نهایی] استفاده کنید.'; + case 'DnsSettingsScreen.ispCanNotEmpty': return 'ISP نمی‌تواند خالی باشد'; + case 'DnsSettingsScreen.urlCanNotEmpty': return 'URL نمی‌تواند خالی باشد'; + case 'DnsSettingsScreen.error': return ({required Object p}) => 'نوع پشتیبانی نشده:${p}'; + case 'DnsSettingsScreen.dnsDesc': return 'ستون اول داده‌های تأخیر، تأخیر ارتباط مستقیم است؛\nستون دوم: روشن کردن [[ترافیک پروکسی] برای حل و فصل DNS از طریق سرور پراکسی]: داده‌های تأخیر، تأخیر درخواست ارسال شده از طریق سرور پراکسی فعلی است [[ترافیک پروکسی] روشن نیست، از طریق سرور پروکسی DNS را حل می‌کند]: داده‌های تأخیر تأخیر درخواست اتصال مستقیم است'; + case 'FeedbackScreen.content': return 'محتوای بازخورد'; + case 'FeedbackScreen.contentHit': return 'الزامی، تا 500 حرف'; + case 'FeedbackScreen.contentCannotEmpty': return 'محتوای بازخورد نمی‌تواند خالی باشد'; + case 'FileContentViewerScreen.title': return 'نمایش دهنده محتوای فایل'; + case 'FileContentViewerScreen.chooseFile': return 'انتخاب فایل'; + case 'FileContentViewerScreen.clearFileContent': return 'آیا از پاکسازی محتوای فایل اطمینان دارید؟'; + case 'FileContentViewerScreen.clearFileContentTips': return 'آیا از پاکسازی محتوای فایل پروفایل اطمینان دارید؟ پاکسازی محتوای فایل پروفایل ممکن است باعث از دست رفتن داده یا عملیات غیرعادی نرم‌افزار شود؛ لطفا با احتیاط عمل کنید.'; + case 'HomeScreen.toSelectServer': return 'لطفا یک سرور انتخاب کنید'; + case 'HomeScreen.invalidServer': return 'نامعتبر است، لطفا مجدد انتخاب کنید'; + case 'HomeScreen.disabledServer': return 'غیرفعال است، لطفا مجدد انتخاب کنید'; + case 'HomeScreen.expiredServer': return 'هیچ سروری در دسترس نیست: ممکن است پیکربندی قدیمی یا غیرفعال باشد'; + case 'HomeScreen.systemProxyTips': return ({required Object sp, required Object hp}) => 'socks:${sp},http(s):${hp}'; + case 'HomeScreen.trafficTotal': return 'کل ترافیک'; + case 'HomeScreen.trafficProxy': return 'ترافیک پروکسی'; + case 'HomeScreen.myLinkEmpty': return 'لطفا قبل‌از استفاده [لینک میان‌بر] را راه‌اندازی کنید'; + case 'HomeScreen.deviceNoSpace': return 'فضای خالی کافی ندارید'; + case 'HomeScreen.tooMuchServers': return ({required Object p, required Object p1}) => 'تعداد زیادی سرور پروکسی [${p}>${p1}] وجود دارد و ممکن است به دلیل محدودیت حافظه سیستم، اتصال امکان پذیر نباشد.'; + case 'LaunchFailedScreen.invalidProcess': return 'اجرای نرم‌افزار ناموفق بود [نام‌ اجرایی پروسه نامعتبر]، لطفا مجدد نرم‌افزار را در دایرکتوری دیگری نصب کنید'; + case 'LaunchFailedScreen.invalidProfile': return 'اجرای نرم‌افزار ناموفق بود [دسترسی به پروفایل ناموفق بود]، لطفا مجدد نرم افزار را نصب کنید'; + case 'LaunchFailedScreen.invalidVersion': return 'اجرای نرم‌افزار ناموفق بود [ورژن نامعتبر]، لطفا مجدد نرم‌افزار را نصب کنید'; + case 'LaunchFailedScreen.systemVersionLow': return 'راه اندازی برنامه ناموفق بود [نسخه سیستم خیلی کم است]'; + case 'LaunchFailedScreen.invalidInstallPath': return 'مسیر نصب نامعتبر است، لطفا مجدد در مسیر معتبر نصب کنید'; + case 'MyProfilesEditScreen.title': return 'ویرایش پروفایل'; + case 'MyProfilesEditScreen.urlExist': return 'آدرس URL از‌قبل وجود دارد، لطفا از URL دیگری استفاده کنید'; + case 'MyProfilesEditScreen.updateTimerInterval': return 'فاصله‌ی به‌روزرسانی'; + case 'MyProfilesEditScreen.updateTimerIntervalTips': return 'حداقل: 5 متر'; + case 'MyProfilesEditScreen.reloadAfterProfileUpdate': return 'بارگذاری مجدد پس‌از به‌روزرسانی پروفایل'; + case 'MyProfilesEditScreen.testLatencyAfterProfileUpdate': return 'شروع تست تاخیر پس‌از به‌روزرسانی خودکار پروفایل'; + case 'MyProfilesEditScreen.testLatencyAfterProfileUpdateTips': return 'وی‌پی‌ان باید روشن و [بارگذاری مجدد پس‌از به‌روزرسانی پروفایل] فعال باشد'; + case 'MyProfilesEditScreen.testLatencyAutoRemove': return 'خودکار سرورهای ناموفق در تست تاخیر را حذف کن'; + case 'MyProfilesEditScreen.testLatencyAutoRemoveTips': return 'تا سه بار امتحان کنید'; + case 'MyProfilesMergeScreen.profilesMerge': return 'ادغام پروفایل‌ها'; + case 'MyProfilesMergeScreen.profilesMergeTarget': return 'پروفایل هدف'; + case 'MyProfilesMergeScreen.profilesMergeSource': return 'پروفایل مرجع'; + case 'MyProfilesMergeScreen.profilesMergeTips': return 'راهنمایی: انحراف پروفایل مرجع حذف می‌شود'; + case 'MyProfilesScreen.title': return 'پروفایل‌ها'; + case 'MyProfilesScreen.atLeastOneEnable': return 'نمی‌تواند غیرغعال شود، لطفا حداقل یک پروفایل را فعال نگه دارید'; + case 'NetCheckScreen.title': return 'بررسی شبکه'; + case 'NetCheckScreen.warn': return 'توجه: به دلیل تأثیر محیط شبکه و قوانین انحراف، نتایج آزمون کاملاً معادل نتایج واقعی نیست.'; + case 'NetCheckScreen.check': return 'بررسی'; + case 'NetCheckScreen.invalidDomain': return 'نام دامنه نامعتبر'; + case 'NetCheckScreen.connectivity': return 'اتصال شبکه'; + case 'NetCheckScreen.connectivityTestIpv4AllFailed': return ({required Object p}) => 'تست اتصال Ipv4 همه‌ی [${p}] ناموفق بودند'; + case 'NetCheckScreen.connectivityTestIpv4Ok': return 'اتصال Ipv4 موفق بود'; + case 'NetCheckScreen.connectivityTestIpv6AllFailed': return ({required Object p}) => 'تست اتصال Ipv6 همه‌ی [${p}] ناموفق بودند، شاید شبکه شما از Ipv6 پشتیبانی نکند'; + case 'NetCheckScreen.connectivityTestIpv6Ok': return 'اتصال Ipv6 موفق بود'; + case 'NetCheckScreen.connectivityTestOk': return 'شبکه به اینترنت متصل است'; + case 'NetCheckScreen.connectivityTestFailed': return 'شبکه هنوز به اینترنت متصل نشده'; + case 'NetCheckScreen.remoteRulesetsDownloadOk': return 'همه با موفقیت دانلود شدند'; + case 'NetCheckScreen.remoteRulesetsDownloadNotOk': return 'دانلود شد یا ناموفق بود'; + case 'NetCheckScreen.outbound': return 'سرور پروکسی'; + case 'NetCheckScreen.outboundOk': return ({required Object p}) => '[${p}] اتصال موفق بود'; + case 'NetCheckScreen.outboundFailed': return ({required Object p1, required Object p2}) => '[${p1}] اتصال ناموفق \nارور:[${p2}]'; + case 'NetCheckScreen.dnsServer': return 'سرور دی‌ان‌اس'; + case 'NetCheckScreen.dnsOk': return ({required Object p1, required Object p2, required Object p3, required Object p4}) => '[${p1}]DNS query succeeded\nDNS Rule: درخواست دی‌ان‌اس موفق بود\nقانون دی‌ان‌اس: [${p2}]\nتاخیر: [${p3} ms]\nآدرس [${p4}]'; + case 'NetCheckScreen.dnsFailed': return ({required Object p1, required Object p2, required Object p3}) => '[${p1}]جستجوی DNS موفق بود\nقانون DNS: [${p2}]\nخطا:[${p3}]'; + case 'NetCheckScreen.host': return 'اتصال HTTP'; + case 'NetCheckScreen.hostConnection': return ({required Object p1, required Object p2, required Object p3}) => '[${p1}]\nقانون انحراف: [${p2}]\nسرور پروکسی: [${p3}]'; + case 'NetCheckScreen.hostConnectionOk': return 'اتصال موفق شد'; + case 'NetCheckScreen.hostConnectionFailed': return ({required Object p}) => 'ارتباط ناموفق بود:[${p}]'; + case 'NetConnectionsFilterScreen.title': return 'فیلتر اتصال‌ها'; + case 'NetConnectionsFilterScreen.hostIp': return 'دامنه/آی‌پی'; + case 'NetConnectionsFilterScreen.app': return 'نرم‌افزار'; + case 'NetConnectionsFilterScreen.rule': return 'قانون'; + case 'NetConnectionsFilterScreen.chain': return 'Outbound'; + case 'NetConnectionsScreen.title': return 'اتصال‌ها'; + case 'NetConnectionsScreen.copyAsCSV': return 'در فرمت CAV کپی شد'; + case 'NetConnectionsScreen.selectType': return 'انتخاب نوع انحراف'; + case 'PerAppAndroidScreen.title': return 'پروکسی به‌تفکیک برنامه'; + case 'PerAppAndroidScreen.whiteListMode': return 'حالت لیست سفید'; + case 'PerAppAndroidScreen.whiteListModeTip': return 'وقتی فعال باشد: فقط برنامه‌هایی که انتخاب شده‌اند پروکسی می‌شوند؛ وقتی فعال نباشد: فقط برنامه‌هایی که انتخاب نشده‌اند پروکسی می‌شوند'; + case 'PerAppAndroidScreen.hideSystemApp': return 'برنامه های سیستم را مخفی کنید'; + case 'PerAppAndroidScreen.hideAppIcon': return 'پنهان کردن نماد برنامه'; + case 'PerAppAndroidScreen.enableAppQueryPermission': return 'مجوز [درخواست لیست نرم‌افزار] را روشن کنید'; + case 'QrcodeScreen.tooLong': return 'متن برای نمایش خیلی طولانی است'; + case 'QrcodeScreen.copy': return 'کپی‌کردن لینک'; + case 'QrcodeScreen.open': return 'بازکردن لینک'; + case 'QrcodeScreen.share': return 'اشتراک لینک'; + case 'QrcodeScreen.shareImage': return 'اشتراک کدQR'; + case 'RegionSettingsScreen.title': return 'کشور یا منطقه'; + case 'RegionSettingsScreen.Regions': return 'راهنمایی: لطفا کشور یا منطقه فعلی خود را انتخاب کنید درغیراین‌صورت ممکن‌است باعث مشکلات انحراف شبکه شود'; + case 'ServerSelectScreen.title': return 'انتخاب سرور'; + case 'ServerSelectScreen.autoSelectServer': return 'خودکار سرور با کمترین تاخیر را انتخاب کن'; + case 'ServerSelectScreen.recentUse': return 'اخیرا استفاده‌شده'; + case 'ServerSelectScreen.myFav': return 'علاقه‌مندی‌های من'; + case 'ServerSelectScreen.selectLocal': return ({required Object p}) => 'سرور انتخاب شده یک آدرس محلی است و شاید به درستی عمل نکند :${p}'; + case 'ServerSelectScreen.selectRequireEnableIPv6': return 'سرور انتخاب شده یک آدرس IPv6 است و نیاز به [فعال‌سازی IPv6] دارد'; + case 'ServerSelectScreen.selectDisabled': return 'این سرور غیرفعال شده است'; + case 'ServerSelectScreen.error404': return 'تشخیص تاخیر با یک اخطار مواجه شده‌است، لطفا بررسی کنید که کانفیگی با محتویات یکسان وجود دارد یا خیر'; + case 'SettingsScreen.ispFaq': return ({required Object p}) => 'سوالات متداول[${p}]'; + case 'SettingsScreen.cleanISP': return ({required Object p}) => 'پاک‌سازی ISP [${p}]'; + case 'SettingsScreen.openISP': return 'بازکردن لینک ISP'; + case 'SettingsScreen.cleanISPNoParam': return 'پاک‌سازی اطلاعات ISP'; + case 'SettingsScreen.getTranffic': return 'دریافت ترافیک'; + case 'SettingsScreen.tutorial': return 'آموزش'; + case 'SettingsScreen.commonlyUsedRulesets': return 'قوانین رایج'; + case 'SettingsScreen.howToRemoveAds': return 'نحوه حذف تبلیغات'; + case 'SettingsScreen.htmlBoard': return 'پنل آنلاین'; + case 'SettingsScreen.dnsLeakDetection': return 'تشخیص نشت DNS'; + case 'SettingsScreen.speedTest': return 'تست سرعت'; + case 'SettingsScreen.downloadProfilePreferProxy': return 'برای دانلود پروفایل پروکسی را ترجیح بده'; + case 'SettingsScreen.downloadProfilePreferProxyTips': return 'اگر اکنون متصل هستین، پروفایل ابتدا از پروکسی متصل دانلود می‌شود'; + case 'SettingsScreen.rulesetDirectDownlad': return 'دانلود مستقیم مجموعه قوانین'; + case 'SettingsScreen.hideUnusedDiversionGroup': return 'مخفی‌کردن گروه‌های انحراف به‌کار نرفته'; + case 'SettingsScreen.disableISPDiversionGroup': return 'قوانین انحراف ISP را غیرفعال کنید'; + case 'SettingsScreen.portSetting': return 'پورت'; + case 'SettingsScreen.portSettingRule': return 'قانون محور'; + case 'SettingsScreen.portSettingDirectAll': return 'مستقیم‌شدن همه'; + case 'SettingsScreen.portSettingProxyAll': return 'پروکسی‌شدن همه'; + case 'SettingsScreen.portSettingControl': return 'کنترل و همگام‌سازی'; + case 'SettingsScreen.portSettingCluster': return 'سرویس کلاستر'; + case 'SettingsScreen.modifyPort': return 'اصلاح پورت'; + case 'SettingsScreen.modifyPortOccupied': return 'پورت اشغال شده است لطفا از پورت دیگری استفاده کنید'; + case 'SettingsScreen.ipStrategyTips': return 'قبل‌از فعال‌سازی لطفا مطمعن شوید شبکه شما از IPv6 پشتیبانی می‌کند، وگرنه برخی ترافیک‌ها نمی‌توانند به‌صورت نرمال دردسترس باشند'; + case 'SettingsScreen.tunAppendHttpProxy': return 'پیوست دادن پروکسی HTTP به وی‌پی‌ان'; + case 'SettingsScreen.tunAppendHttpProxyTips': return 'برخی نرم‌افزار‌ها از کارت شبکه مجازی رد میشوند و مستقیم به پروکسی HTTP متصل می‌شوند'; + case 'SettingsScreen.tlsInsecureEnable': return 'رد شدن از تأیید گواهی'; + case 'SettingsScreen.tlsFragmentEnable': return 'بخش بندی TLS را فعال کنید'; + case 'SettingsScreen.tlsFragmentSize': return 'اندازه بخش TLS'; + case 'SettingsScreen.tlsFragmentSleep': return 'خواب بخش‌بندی شده TLS'; + case 'SettingsScreen.tlsMixedCaseSNIEnable': return 'TLS ترکیبی SNI را فعال کنید'; + case 'SettingsScreen.tlsPaddingEnable': return 'فعال کردن TLS Padding'; + case 'SettingsScreen.tlsPaddingSize': return 'اندازه پد TLS'; + case 'SettingsScreen.dnsEnableRule': return 'فعال‌سازی قوانین انحراف دی‌ان‌اس'; + case 'SettingsScreen.dnsEnableFakeIp': return 'فعال‌سازی آی‌پی جعلی'; + case 'SettingsScreen.dnsEnableClientSubnet': return 'ECS را فعال کنید'; + case 'SettingsScreen.dnsEnableProxyResolveByProxy': return 'دی‌ان‌اس را از [ترافیک پروکسی] سرور پروکسی عبور می‌دهد'; + case 'SettingsScreen.dnsEnableFinalResolveByProxy': return 'دی‌ان‌اس را از سرور پروکسی [نهایی] عبور می‌دهد'; + case 'SettingsScreen.dnsTestDomain': return 'تست دامنه'; + case 'SettingsScreen.dnsTestDomainInvalid': return 'دامنه نامعتبر'; + case 'SettingsScreen.dnsTypeOutbound': return 'سرور پروکسی'; + case 'SettingsScreen.dnsTypeDirect': return 'ترافیک مستقیم'; + case 'SettingsScreen.dnsTypeProxy': return 'ترافیک پروکسی'; + case 'SettingsScreen.dnsTypeResolver': return 'سرور دی‌ان‌اس'; + case 'SettingsScreen.dnsEnableRuleTips': return 'بعد از فعال‌سازی نام دامنه، سرور دی‌ان‌اس مربوط را بر اساس قوانین انحراف برای عبور انتخاب می‌کند'; + case 'SettingsScreen.dnsEnableFakeIpTips': return 'پس از فعال کردن FakeIP، اگر اتصال VPN قطع شود، ممکن است برنامه شما نیاز به راه اندازی مجدد داشته باشد [حالت TUN].'; + case 'SettingsScreen.dnsTypeOutboundTips': return 'سامانه نام دامنه (DNS) برای سرور پروکسی'; + case 'SettingsScreen.dnsTypeDirectTips': return 'سامانه نام دامنه (DNS) برای ترافیک مستقیم'; + case 'SettingsScreen.dnsTypeProxyTips': return 'سامانه نام دامنه (DNS) برای ترافیک پروکسی'; + case 'SettingsScreen.dnsTypeResolverTips': return 'سامانه نام دامنه (DNS) برای بقیه سرور دی‌ان‌اس'; + case 'SettingsScreen.dnsTypeFinalTips': return 'سامانه نام دامنه (DNS) برای بقیه ترافیک'; + case 'SettingsScreen.dnsAutoSetServer': return 'به طور خودکار سرور را راه اندازی کنید'; + case 'SettingsScreen.dnsResetServer': return 'بازنشانی سرور'; + case 'SettingsScreen.inboundDomainResolve': return 'حل نام دامنه های ورودی'; + case 'SettingsScreen.privateDirect': return 'اتصال مستقیم شبکه خصوصی'; + case 'SettingsScreen.inboundDomainResolveTips': return ({required Object p}) => 'برخی از نام‌های دامنه بدون قوانین انحراف پیکربندی شده باید حل و فصل شوند تا بتوانند قوانین انحراف مبتنی بر IP را تحت تأثیر قرار دهند [${p}].'; + case 'SettingsScreen.useRomoteRes': return 'از منابع راه‌دور استفاده کنید'; + case 'SettingsScreen.autoSelect': return 'انتخاب خودکار'; + case 'SettingsScreen.autoSelectServerIgnorePerProxyServer': return 'سرور پروکسی [پراکسی جلو] را نادیده بگیرید'; + case 'SettingsScreen.autoSelectServerInterval': return 'بازه زمانی بررسی تاخیر'; + case 'SettingsScreen.autoSelectServerReTestIfNetworkUpdate': return 'شناسایی مجدد زمانی که شبکه تغییر می کند'; + case 'SettingsScreen.autoSelectServerUpdateCurrentServerAfterManualUrltest': return 'سرور فعلی را پس از تشخیص تأخیر دستی به روز کنید'; + case 'SettingsScreen.autoSelectServerIntervalTips': return 'هرچه فاصله تشخیص تاخیر کمتر باشد، داده های تاخیر سرور به موقع به روز می شود، اما منابع بیشتری را اشغال می کند و برق را سریعتر مصرف می کند'; + case 'SettingsScreen.autoSelectServerFavFirst': return 'اولویت استفاده از [علاقه‌مندی‌های من]'; + case 'SettingsScreen.autoSelectServerFavFirstTips': return 'اگر لیست [علاقه‌مندی‌های من] خالی نبود از سرور‌های داخل [علاقه‌مندی‌های من] استفاده کن'; + case 'SettingsScreen.autoSelectServerFilter': return 'فیلترکردن سرور‌های نامعتبر'; + case 'SettingsScreen.autoSelectServerFilterTips': return ({required Object p}) => 'اگر بعد از فیلتر کردن هیچ سروری در دسترس نباشد، از اولین سرورهای [${p}] استفاده خواهد شد.'; + case 'SettingsScreen.autoSelectServerLimitedNum': return 'حداکثر تعداد سرور'; + case 'SettingsScreen.autoSelectServerLimitedNumTips': return 'سرورهای بیش از این تعداد فیلتر خواهند شد'; + case 'SettingsScreen.numInvalid': return 'عدد نامعتبر'; + case 'SettingsScreen.hideInvalidServer': return 'مخفی‌کردن سرور‌های نامعتبر'; + case 'SettingsScreen.sortServer': return 'مرتب‌سازی سرور'; + case 'SettingsScreen.sortServerTips': return 'مرتب‌سازی براساس تاخیر از کم به زیاد'; + case 'SettingsScreen.selectServerHideRecommand': return 'مخفی‌کردن [پیشنهادی]'; + case 'SettingsScreen.selectServerHideRecent': return '‌ مخفی‌کردن [اخیرا استفاده‌شده]'; + case 'SettingsScreen.selectServerHideFav': return 'مخفی‌کردن [علاقه‌مندی‌های من]'; + case 'SettingsScreen.homeScreen': return 'صفحه‌ خانه'; + case 'SettingsScreen.theme': return 'تِم'; + case 'SettingsScreen.myLink': return 'لینک میان‌بر'; + case 'SettingsScreen.myLinkInvalid': return 'URL نامعتبر'; + case 'SettingsScreen.autoConnectAfterLaunch': return 'اتصال خودکار پس‌از راه‌اندازی'; + case 'SettingsScreen.hideAfterLaunch': return 'پنهان کردن پنجره پس از راه اندازی'; + case 'SettingsScreen.autoSetSystemProxy': return 'تنظیم خودکار حالت پروکسی سیستم پس‌از اتصال'; + case 'SettingsScreen.disconnectWhenQuit': return 'قطع اتصال هنگام خروج از نرم‌افزار'; + case 'SettingsScreen.allowBypass': return 'به برنامه‌ها اجازه دهید VPN را دور بزنند'; + case 'SettingsScreen.importSuccess': return 'افزودن موفق بود'; + case 'SettingsScreen.rewriteConfirm': return 'این فایل کانفیگ‌های محلی موجود را بازنویسی می‌کند. آیا می‌خواهید ادامه بدین؟'; + case 'SettingsScreen.networkShare': return 'اشتراک‌گذاری شبکه'; + case 'SettingsScreen.frontProxy': return 'پروکسی جلو'; + case 'SettingsScreen.frontProxyTips': return ({required Object p}) => 'داده-> سرور پروکسی جلویی [پراکسی سرورهای چندگانه: بالا به پایین]-> سرور پروکسی [${p}]-> سرور هدف'; + case 'SettingsScreen.allowOtherHostsConnect': return 'اجازه اتصال دیگران'; + case 'SettingsScreen.allowOtherHostsConnectTips': return ({required Object sp, required Object hp}) => 'socks:${sp},http(s):${hp}'; + case 'SettingsScreen.tunAutoRoute': return 'Auto Route'; + case 'SettingsScreen.tunStrictRoute': return 'Strict Route'; + case 'SettingsScreen.tunStrictRouteTips': return 'اگر پس از روشن کردن اشتراک‌گذاری، دیگران نمی‌توانند به این دستگاه دسترسی داشته باشند، لطفاً این سوئیچ را خاموش کنید.'; + case 'SettingsScreen.enableCluster': return 'فعال‌سازی پروکسی Socks/Http خوشه‌ای'; + case 'SettingsScreen.clusterAllowOtherHostsConnect': return 'اجازه اتصال دیگران به خوشه'; + case 'SettingsScreen.clusterAllowOtherHostsConnectTips': return ({required Object ip, required Object port}) => 'http://${ip}:${port}/get_proxies'; + case 'SettingsScreen.clusterAuth': return 'احراز هویت خوشه پروکسی'; + case 'SettingsScreen.tunMode': return 'حالت TUN'; + case 'SettingsScreen.tunModeTips': return 'حالت TUN تمام ترافیک سیستم را تحت کنترل خواهد گرفت [دراین حالت می‌توانید پروکسی سیستم را غیرفعال نگه‌ دارید)'; + case 'SettingsScreen.tunModeRunAsAdmin': return 'حالت TUN نیازمند مجوز مدیر سیستم می‌باشد لطفا نرم‌افزار را مجدد با حالت مدیر (administrator) راه‌اندازی کنید'; + case 'SettingsScreen.tunStack': return 'Stack'; + case 'SettingsScreen.launchAtStartup': return 'اجرا در راه‌اندازی'; + case 'SettingsScreen.quitWhenSwitchSystemUser': return 'خروج از نرم‌افزار هنگام تعویض کاربران سیستم'; + case 'SettingsScreen.handleScheme': return 'فراخوانی Scheme سیستم'; + case 'SettingsScreen.portableMode': return 'حالت قابل‌حمل'; + case 'SettingsScreen.portableModeDisableTips': return 'اگر نیاز دارین از حالت قابل‌حمل خارج شوید لطفا از [Karing] خارج شده و به‌صورت دستی پوشه [Profiles] هم مسیر با فایل [karing.exe] را حذف کنید'; + case 'SettingsScreen.handleKaringScheme': return 'رسیدگی به ندای karing://'; + case 'SettingsScreen.handleClashScheme': return 'رسیدگی به‌ ندای clash://'; + case 'SettingsScreen.handleSingboxScheme': return 'رسیدگی به ندای sing-box://'; + case 'SettingsScreen.alwayOnVPN': return 'اتصال همیشه باز'; + case 'SettingsScreen.removeSystemVPNConfig': return 'حذف پیکربندی وی‌پی‌ان سیستم'; + case 'SettingsScreen.timeConnectOrDisconnect': return 'اتصال/قطع اتصال برنامه‌ریزی شده'; + case 'SettingsScreen.timeConnectOrDisconnectTips': return 'برای اعمال شدن وی‌پی‌ان باید متصل باشد. پس‌از روشن‌شدن [خواب خودکار] غیرفعال می‌شود'; + case 'SettingsScreen.timeConnectAndDisconnectInterval': return ({required Object p}) => 'فاصله اتصال/قطع اتصال نمی تواند کمتر از ${p} دقیقه باشد'; + case 'SettingsScreen.disableFontScaler': return 'غیرفعال‌سازی مقیاس‌بندی فونت(با راه‌اندازی مجدد اعمال می‌شود)'; + case 'SettingsScreen.autoOrientation': return 'چرخش صفحه را دنبال کنید'; + case 'SettingsScreen.restartTakesEffect': return 'با راه‌اندازی مجدد اعمال می‌شود'; + case 'SettingsScreen.resetSettings': return 'بازنشانی تنظیمات'; + case 'SettingsScreen.cleanCache': return 'پاک کردن حافظه پنهان'; + case 'SettingsScreen.cleanCacheDone': return 'پاکسازی کامل شد'; + case 'SettingsScreen.appleTestFlight': return 'تست‌فلایت اپل'; + case 'SettingsScreen.appleAppStore': return 'اپ‌استور اپل'; + case 'SettingsScreen.hasNewVersion': return ({required Object p}) => 'به‌روزرسانی نسخه ${p} '; + case 'SettingsScreen.follow': return 'مارو دنبال کنید'; + case 'SettingsScreen.contactUs': return 'ارتباط باما'; + case 'SettingsScreen.rateInApp': return 'امتیاز به ما'; + case 'SettingsScreen.rateInAppStore': return 'به ما در اپ‌استور امتیاز بدین'; + case 'SpeedTestSettingsScreen.title': return 'URL تست سرعت'; + case 'TextToQrCodeScreen.title': return 'متن به کد QR'; + case 'TextToQrCodeScreen.convert': return 'تبدیل'; + case 'UserAgreementScreen.privacyFirst': return 'حریم‌خصوصی شما اولویت دارد'; + case 'UserAgreementScreen.agreeAndContinue': return 'پذیرفتن و ادامه'; + case 'VersionUpdateScreen.versionReady': return ({required Object p}) => 'نسخه جدید [${p}] آماده است'; + case 'VersionUpdateScreen.update': return 'راه‌اندازی مجدد برای به‌روزرسانی'; + case 'VersionUpdateScreen.cancel': return 'الان‌ نه'; + case 'CommonWidget.diableAlwayOnVPN': return 'اگر [وی‌پی‌ان همیشه روشن] روشن است لطفا [وی‌پی‌ان همیشه روشن] را خاموش کنید و مجدد برای اتصال تلاش کنید'; + case 'CommonWidget.resetPort': return 'لطفاً پورت را به پورت موجود دیگری تغییر دهید یا برنامه ای را که پورت را اشغال می کند ببندید.'; + case 'ServerManager.noServerAvaliable': return 'هیچ سروری در دسترس نیست، لطفاً مطمئن شوید که پیوند پیکربندی یا فایل پیکربندی معتبر است، اگر پیکربندی شما از GitHub آمده است، لطفاً آدرس پیوند را از دکمه [Raw] در صفحه دریافت کنید'; + case 'ServerManager.filePathCannotEmpty': return 'مسیر فایل نمی‌تواند خالی باشد'; + case 'ServerManager.fileNotExist': return ({required Object p}) => 'فایل وجود ندارد:${p}'; + case 'ServerManager.urlCannotEmpty': return 'لینک نمی‌تواند خالی باشد'; + case 'ServerManager.invalidUrl': return 'لینک پروفایل نامعتبر است'; + case 'ServerManager.parseFailed': return 'تجزیه پروفایل انجام نشد'; + case 'main.tray.menuOpen': return ' بازکردن '; + case 'main.tray.menuExit': return ' بستن '; + case 'enable': return 'فعال‌سازی'; + case 'disable': return 'غیرفعال'; + case 'filter': return 'فیلتر'; + case 'filterMethod': return 'روش فیلتر'; + case 'include': return 'شامل شود'; + case 'exclude': return 'حذف کردن'; + case 'all': return 'همه'; + case 'prefer': return 'اولویت'; + case 'only': return 'فقط'; + case 'open': return 'باز کن'; + case 'close': return 'بسته'; + case 'quit': return 'خروج'; + case 'add': return 'افزودن'; + case 'remove': return 'حذف'; + case 'edit': return 'ویرایش کنید'; + case 'view': return 'بررسی'; + case 'more': return 'بیشتر'; + case 'addProfile': return 'افزودن پروفایل'; + case 'addSuccess': return 'با‌موفقیت اضافه شد'; + case 'addSuccessThen': return ({required Object p}) => 'پیکربندی با موفقیت ایجاد شد، لطفاً برای مشاهده به [${p}] بروید'; + case 'addFailed': return ({required Object p}) => 'افزودن ناموفق بود:${p}'; + case 'removeConfirm': return 'آیا از حذف اطمینان دارین؟'; + case 'tips': return 'اطلاعات'; + case 'copy': return 'کپی'; + case 'ok': return 'خُب'; + case 'cancel': return 'لغو'; + case 'feedback': return 'بازخورد'; + case 'faq': return 'سوالات متداول'; + case 'download': return 'دانلود'; + case 'loading': return 'درحال بارگذاری…'; + case 'updateFailed': return ({required Object p}) => 'به‌روزرسانی ناموفق بود:${p}'; + case 'days': return 'روز'; + case 'hours': return 'ساعت'; + case 'minutes': return 'دقیقه'; + case 'seconds': return 'دومین'; + case 'protocol': return 'پروتکل'; + case 'search': return 'جستجو'; + case 'custom': return 'سفارشی'; + case 'connect': return 'اتصال'; + case 'disconnect': return 'قطع‌ اتصال'; + case 'connected': return 'وصل شد'; + case 'disconnected': return 'قطع شد'; + case 'connecting': return 'درحال اتصال'; + case 'connectTimeout': return 'اتمام مهلت اتصال'; + case 'timeout': return 'تایم اوت'; + case 'language': return 'زبان'; + case 'next': return 'بعدی'; + case 'done': return 'انجام‌شد'; + case 'apply': return 'درخواست دادن'; + case 'refresh': return 'بارگذاری مجدد'; + case 'retry': return 'دوباره امتحان کنید؟'; + case 'none': return 'هیچ‌کدام'; + case 'reset': return 'ریست'; + case 'submit': return 'ارسال'; + case 'account': return 'نام‌کاربری'; + case 'password': return 'رمز‌عبور'; + case 'required': return 'الزامی'; + case 'diversion': return 'انحراف'; + case 'diversionRules': return 'قوانین انحراف'; + case 'diversionRulesEnable': return 'قوانین بارگیری [ISP] را فعال کنید'; + case 'diversionCustomGroup': return 'گروه انحراف سفارشی'; + case 'diversionCustomGroupPreset': return 'از پیش تنظیم شده [گروه انحراف سفارشی]'; + case 'diversionCustomGroupPresetTips': return 'توجه: موارد فعال به [گروه انحراف سفارشی] و [قوانین انحراف] اضافه/پوشش داده خواهند شد'; + case 'diversionCustomGroupAddTips': return 'توجه: ممکن است لازم باشد پس از افزودن مرتب‌سازی به‌صورت دستی آن را تنظیم کنید، در غیر این صورت انحراف تازه اضافه‌شده ممکن است اعمال نشود.'; + case 'urlTestCustomGroup': return 'گروه پروکسی سفارشی'; + case 'rulesetEnableTips': return 'راهنمایی: پس‌از ذخیره کردن لطفا به [قوانین انحراف] رفته و قوانین مربوط زا تنظیم کنید؛ درغیراین صورت اعمال نخواهند شد'; + case 'ispUserAgentTips': return '[ISP] انواع مختلف داده های اشتراک را بر اساس [UserAgent] در درخواست [HTTP] ارائه خواهد کرد.'; + case 'ispDiversionTips': return 'قوانین بارگذاری ارائه شده توسط [ISP]، اشتراک های نوع [V2Ray] از قوانین تخلیه پشتیبانی نمی کنند'; + case 'staticIP': return 'IP استاتیک'; + case 'other': return 'دیگر'; + case 'dns': return 'DNS'; + case 'url': return 'URL'; + case 'isp': return 'ISP'; + case 'tls': return 'TLS'; + case 'userAgent': return 'UserAgent'; + case 'urlInvalid': return 'URL نامعتبر'; + case 'outboundActionCurrentSelected': return 'فعلی انتخاب شده'; + case 'outboundActionUrltest': return 'انتخاب خودکار'; + case 'outboundActionDirect': return 'مستقیم'; + case 'outboundActionBlock': return 'مسدود'; + case 'routeFinal': return 'نهایی'; + case 'rulesetGeoSite': return 'GeoSite'; + case 'rulesetGeoIp': return 'GeoIP'; + case 'rulesetAcl': return 'ACL'; + case 'iCloud': return 'iCloud'; + case 'appleTV': return 'Apple TV'; + case 'webdav': return 'Webdav'; + case 'setting': return 'تنظیمات'; + case 'protocolSniff': return 'تشخیص پروتکل'; + case 'protocolSniffOverrideDestination': return 'نام دامنه شناسایی شده آدرس هدف اتصال را پوشش می دهد'; + case 'remark': return 'ملاحضات'; + case 'remarkCannotEmpty': return 'ملاحظات نمی‌تواند خالی باشد'; + case 'remarkTooLong': return 'ملاحظات تا ۳۲ حرف'; + case 'remarkExist': return 'ملاحظات از‌قبل وجود دارد، لطفا از نام دیگری استفاده کنید'; + case 'domainSuffix': return 'پسوند دامنه'; + case 'domain': return 'دامنه'; + case 'domainKeyword': return 'کلید‌واژه دامنه'; + case 'domainRegex': return 'عبارات باقاعده ی دامنه (Regex)'; + case 'ip': return 'IP'; + case 'port': return 'پورت'; + case 'appPackage': return 'نام بسته‌ی برنامه'; + case 'processName': return 'نام اجرایی پروسه'; + case 'processPath': return 'مسیر پروسه'; + case 'systemProxy': return 'پروکسی سیستم'; + case 'netInterfaces': return 'رابط شبکه'; + case 'netSpeed': return 'سرعت'; + case 'website': return 'وبسایت'; + case 'rule': return 'قانون'; + case 'global': return 'عمومی'; + case 'qrcode': return 'کد QR'; + case 'scanQrcode': return 'اسکن QRکد'; + case 'scanResult': return 'نتایج اسکن'; + case 'backupAndSync': return 'پشتیبان‌گیری و همگام‌سازی'; + case 'importAndExport': return 'وارد‌کردن و خروجی‌گرفتن'; + case 'import': return 'وارد‌کردن'; + case 'export': return 'خروجی‌گرفتن'; + case 'send': return 'ارسال کنید'; + case 'receive': return 'تصاحب'; + case 'sendOrReceiveNotMatch': return ({required Object p}) => 'لطفا از [${p}] استفاده کنید'; + case 'sendConfirm': return 'ارسال را تایید کرد؟'; + case 'termOfUse': return 'شرایط استفاده'; + case 'privacyPolicy': return 'سیاست حریم خصوصی'; + case 'about': return 'درباره'; + case 'name': return 'نام'; + case 'version': return 'نسخه'; + case 'notice': return 'اطلاعیه'; + case 'sort': return 'مرتب‌سازی'; + case 'novice': return 'حالت مبتدی'; + case 'recommended': return 'پیشنهادی'; + case 'innerError': return ({required Object p}) => 'خطای داخلی: ${p}'; + case 'logicOperation': return 'عملیات منطقی'; + case 'share': return 'اشتراک گذاری'; + case 'candidateWord': return 'کلمات نامزد'; + case 'keywordOrRegx': return 'کلمات کلیدی / معمولی'; + case 'importFromClipboard': return 'افزودن از کلیپ‌برد'; + case 'exportToClipboard': return 'صادرات به کلیپ بورد'; + case 'server': return 'سرور'; + case 'appleTVConnectTurnOfprivateDirect': return 'لطفاً ابتدا [اتصال مستقیم شبکه خصوصی] را فعال کنید'; + case 'targetConnectFailed': return ({required Object p}) => 'اتصال به [${p}] ناموفق بود، لطفاً مطمئن شوید که دستگاه در همان LAN است و [اتصال مستقیم شبکه خصوصی] را فعال کنید.'; + case 'appleTVSync': return 'همگام سازی پیکربندی هسته فعلی با Apple TV - Karing'; + case 'appleTVSyncDone': return 'همگام سازی کامل شد، لطفاً برای باز کردن/راه اندازی مجدد اتصال به Apple TV - Karing بروید'; + case 'appleTVRemoveCoreConfig': return 'حذف Apple TV - Karing Core Configuration'; + case 'appleTVRemoveCoreConfigDone': return 'Apple TV - نمایه اصلی کارینگ حذف شد'; + case 'appleTVUrlInvalid': return 'URL نامعتبر است، لطفاً Apple TV - Karing را باز کنید، کد QR نمایش داده شده توسط Karing را اسکن کنید'; + case 'remoteProfileEditConfirm': return 'پس از به روز رسانی تنظیمات، تغییرات گره بازیابی می شوند آیا می خواهید ادامه دهید؟'; + case 'invalidFileType': return ({required Object p}) => 'نوع فایل نامعتبر:${p}'; + case 'mustBeValidHttpsURL': return 'باید یک URL معتبر https باشد'; + case 'fileNotExistReinstall': return ({required Object p}) => 'فایل [${p}] وجود ندارد، لطفا دوباره نصب کنید'; + case 'latencyTest': return 'بررسی تاخیر'; + case 'latencyTestResolveIP': return 'در طی تشخیص دستی، IP صادرات نیز تجزیه و تحلیل می شود.'; + case 'uwpExemption': return 'معافیت جداسازی شبکه UWP'; + case 'removeBannerAds': return 'تبلیغات را حذف کنید'; + case 'removeBannerAdsByReward': return 'چند ثانیه تبلیغات را تماشا کنید و 7 روز بدون تبلیغات پاداش خواهید گرفت'; + case 'removeBannerAdsByRewardDone': return 'یک پاداش 7 روزه بدون آگهی دریافت کرد'; + case 'locales.en': return 'English'; + case 'locales.zh-CN': return '简体中文'; + case 'locales.ar': return 'عربي'; + case 'locales.ru': return 'Русский'; + case 'locales.fa': return 'فارسی'; + default: return null; + } + } +} + diff --git a/lib/i18n/strings_fa.i18n.json b/lib/i18n/strings_fa.i18n.json index f67f901..7a48458 100644 --- a/lib/i18n/strings_fa.i18n.json +++ b/lib/i18n/strings_fa.i18n.json @@ -20,7 +20,7 @@ "AddProfileByLinkOrContentScreen": { "title": "افزودن لینک پروفایل", "updateTimerInterval": "فاصله‌ی به‌روزرسانی", - "updateTimerIntervalTips": "برای غیرفعال‌ کردن لطفا تنظیم کنید روی:<5m", + "updateTimerIntervalTips": "حداقل: 5 متر", "profileLinkContent": "لینک/محتوای پروفایل", "profileLinkContentHit": "لینک/محتوای پروفایل [الزامی] (پشتیبانی از کلش، V2ray(پشتیبانی به‌صورت دسته‌ای)، لینک‌های پروفایل فرعی)، استش، کارینگ، سینگ‌باکس، شدوساکس، لینک‌های پروفایل فرعی)", "subscriptionCannotEmpty": "لینک پروفایل نمی‌تواند خالی باشد", @@ -102,13 +102,13 @@ "invalidProfile": "اجرای نرم‌افزار ناموفق بود [دسترسی به پروفایل ناموفق بود]، لطفا مجدد نرم افزار را نصب کنید", "invalidVersion": "اجرای نرم‌افزار ناموفق بود [ورژن نامعتبر]، لطفا مجدد نرم‌افزار را نصب کنید", "systemVersionLow": "راه اندازی برنامه ناموفق بود [نسخه سیستم خیلی کم است]", - "startFromUNC": "مسیر نصب نامعتبر است، لطفا مجدد در مسیر معتبر نصب کنید" + "invalidInstallPath": "مسیر نصب نامعتبر است، لطفا مجدد در مسیر معتبر نصب کنید" }, "MyProfilesEditScreen": { "title": "ویرایش پروفایل", "urlExist": "آدرس URL از‌قبل وجود دارد، لطفا از URL دیگری استفاده کنید", "updateTimerInterval": "فاصله‌ی به‌روزرسانی", - "updateTimerIntervalTips": "برای غیرفعال‌ کردن لطفا تنظیم کنید روی:<5m", + "updateTimerIntervalTips": "حداقل: 5 متر", "reloadAfterProfileUpdate": "بارگذاری مجدد پس‌از به‌روزرسانی پروفایل", "testLatencyAfterProfileUpdate": "شروع تست تاخیر پس‌از به‌روزرسانی خودکار پروفایل", "testLatencyAfterProfileUpdateTips": "وی‌پی‌ان باید روشن و [بارگذاری مجدد پس‌از به‌روزرسانی پروفایل] فعال باشد", @@ -215,6 +215,7 @@ "portSettingControl": "کنترل و همگام‌سازی", "portSettingCluster": "سرویس کلاستر", "modifyPort": "اصلاح پورت", + "modifyPortOccupied": "پورت اشغال شده است لطفا از پورت دیگری استفاده کنید", "ipStrategyTips": "قبل‌از فعال‌سازی لطفا مطمعن شوید شبکه شما از IPv6 پشتیبانی می‌کند، وگرنه برخی ترافیک‌ها نمی‌توانند به‌صورت نرمال دردسترس باشند", "tunAppendHttpProxy": "پیوست دادن پروکسی HTTP به وی‌پی‌ان", "tunAppendHttpProxyTips": "برخی نرم‌افزار‌ها از کارت شبکه مجازی رد میشوند و مستقیم به پروکسی HTTP متصل می‌شوند", @@ -277,16 +278,11 @@ "autoSetSystemProxy": "تنظیم خودکار حالت پروکسی سیستم پس‌از اتصال", "disconnectWhenQuit": "قطع اتصال هنگام خروج از نرم‌افزار", "allowBypass": "به برنامه‌ها اجازه دهید VPN را دور بزنند", - "lanSyncTo": "همگام‌سازی با دیگران", - "lanSyncFrom": "همگام‌سازی از دیگران", - "lanSyncScanQRcode": "اسکن کدQR و همگام‌سازی", - "syncToConfirm": "همگام سازی را با طرف مقابل تأیید می کنید؟", - "syncDone": "همگام سازی تکمیل شد", "importSuccess": "افزودن موفق بود", "rewriteConfirm": "این فایل کانفیگ‌های محلی موجود را بازنویسی می‌کند. آیا می‌خواهید ادامه بدین؟", "networkShare": "اشتراک‌گذاری شبکه", "frontProxy": "پروکسی جلو", - "frontProxyTips": "داده‌ها->سرور پروکسی جلو->سرور پروکسی->سرور هدف", + "frontProxyTips": "داده-> سرور پروکسی جلویی [پراکسی سرورهای چندگانه: بالا به پایین]-> سرور پروکسی [$p]-> سرور هدف", "allowOtherHostsConnect": "اجازه اتصال دیگران", "allowOtherHostsConnectTips": "socks:$sp,http(s):$hp", "tunAutoRoute": "Auto Route", @@ -294,9 +290,8 @@ "tunStrictRouteTips": "اگر پس از روشن کردن اشتراک‌گذاری، دیگران نمی‌توانند به این دستگاه دسترسی داشته باشند، لطفاً این سوئیچ را خاموش کنید.", "enableCluster": "فعال‌سازی پروکسی Socks/Http خوشه‌ای", "clusterAllowOtherHostsConnect": "اجازه اتصال دیگران به خوشه", - "clusterAllowOtherHostsConnectTips": "http://127.0.0.1:$hp/get_proxies", + "clusterAllowOtherHostsConnectTips": "http://$ip:$port/get_proxies", "clusterAuth": "احراز هویت خوشه پروکسی", - "clusterConfirm": "لطفا مطمعن شوید تاخیر سرورها بررسی شده و درصورتی‌که بررسی نشده‌باشند یا اشتباه بررسی شده‌باشند سرویس پروکسی ساخته نمی‌شود", "tunMode": "حالت TUN", "tunModeTips": "حالت TUN تمام ترافیک سیستم را تحت کنترل خواهد گرفت [دراین حالت می‌توانید پروکسی سیستم را غیرفعال نگه‌ دارید)", "tunModeRunAsAdmin": "حالت TUN نیازمند مجوز مدیر سیستم می‌باشد لطفا نرم‌افزار را مجدد با حالت مدیر (administrator) راه‌اندازی کنید", @@ -309,10 +304,11 @@ "handleKaringScheme": "رسیدگی به ندای karing://", "handleClashScheme": "رسیدگی به‌ ندای clash://", "handleSingboxScheme": "رسیدگی به ندای sing-box://", + "alwayOnVPN": "اتصال همیشه باز", "removeSystemVPNConfig": "حذف پیکربندی وی‌پی‌ان سیستم", "timeConnectOrDisconnect": "اتصال/قطع اتصال برنامه‌ریزی شده", "timeConnectOrDisconnectTips": "برای اعمال شدن وی‌پی‌ان باید متصل باشد. پس‌از روشن‌شدن [خواب خودکار] غیرفعال می‌شود", - "timeConnectAndDisconnectInterval": "The connection/disconnection interval cannot be less than $p minutes", + "timeConnectAndDisconnectInterval": "فاصله اتصال/قطع اتصال نمی تواند کمتر از $p دقیقه باشد", "disableFontScaler": "غیرفعال‌سازی مقیاس‌بندی فونت(با راه‌اندازی مجدد اعمال می‌شود)", "autoOrientation": "چرخش صفحه را دنبال کنید", "restartTakesEffect": "با راه‌اندازی مجدد اعمال می‌شود", @@ -328,17 +324,12 @@ "rateInAppStore": "به ما در اپ‌استور امتیاز بدین" }, "SpeedTestSettingsScreen": { - "title": "URL تست سرعت", - "error": "باید یک URL معتبر https باشد" + "title": "URL تست سرعت" }, "TextToQrCodeScreen": { "title": "متن به کد QR", "convert": "تبدیل" }, - "UrlTestSettingsScreen": { - "title": "URL بررسی تاخیر", - "error": "باید یک URL معتبر https باشد" - }, "UserAgreementScreen": { "privacyFirst": "حریم‌خصوصی شما اولویت دارد", "agreeAndContinue": "پذیرفتن و ادامه" @@ -368,6 +359,11 @@ }, "enable": "فعال‌سازی", "disable": "غیرفعال", + "filter": "فیلتر", + "filterMethod": "روش فیلتر", + "include": "شامل شود", + "exclude": "حذف کردن", + "all": "همه", "prefer": "اولویت", "only": "فقط", "open": "باز کن", @@ -477,6 +473,10 @@ "importAndExport": "وارد‌کردن و خروجی‌گرفتن", "import": "وارد‌کردن", "export": "خروجی‌گرفتن", + "send": "ارسال کنید", + "receive": "تصاحب", + "sendOrReceiveNotMatch": "لطفا از [$p] استفاده کنید", + "sendConfirm": "ارسال را تایید کرد؟", "termOfUse": "شرایط استفاده", "privacyPolicy": "سیاست حریم خصوصی", "about": "درباره", @@ -490,7 +490,7 @@ "logicOperation": "عملیات منطقی", "share": "اشتراک گذاری", "candidateWord": "کلمات نامزد", - "keywordsOrRegx": "کلمات کلیدی / معمولی", + "keywordOrRegx": "کلمات کلیدی / معمولی", "importFromClipboard": "افزودن از کلیپ‌برد", "exportToClipboard": "صادرات به کلیپ بورد", "server": "سرور", @@ -503,6 +503,14 @@ "appleTVUrlInvalid": "URL نامعتبر است، لطفاً Apple TV - Karing را باز کنید، کد QR نمایش داده شده توسط Karing را اسکن کنید", "remoteProfileEditConfirm": "پس از به روز رسانی تنظیمات، تغییرات گره بازیابی می شوند آیا می خواهید ادامه دهید؟", "invalidFileType": "نوع فایل نامعتبر:$p", + "mustBeValidHttpsURL": "باید یک URL معتبر https باشد", + "fileNotExistReinstall": "فایل [$p] وجود ندارد، لطفا دوباره نصب کنید", + "latencyTest": "بررسی تاخیر", + "latencyTestResolveIP": "در طی تشخیص دستی، IP صادرات نیز تجزیه و تحلیل می شود.", + "uwpExemption": "معافیت جداسازی شبکه UWP", + "removeBannerAds": "تبلیغات را حذف کنید", + "removeBannerAdsByReward": "چند ثانیه تبلیغات را تماشا کنید و 7 روز بدون تبلیغات پاداش خواهید گرفت", + "removeBannerAdsByRewardDone": "یک پاداش 7 روزه بدون آگهی دریافت کرد", "locales(map)": { "en": "English", "zh-CN": "简体中文", diff --git a/lib/i18n/strings_ru.g.dart b/lib/i18n/strings_ru.g.dart new file mode 100644 index 0000000..8168c87 --- /dev/null +++ b/lib/i18n/strings_ru.g.dart @@ -0,0 +1,1281 @@ +/// +/// Generated file. Do not edit. +/// +// coverage:ignore-file +// ignore_for_file: type=lint, unused_import + +import 'package:flutter/widgets.dart'; +import 'package:intl/intl.dart'; +import 'package:slang/generated.dart'; +import 'strings.g.dart'; + +// Path: +class TranslationsRu implements Translations { + /// You can call this constructor and build your own translation instance of this locale. + /// Constructing via the enum [AppLocale.build] is preferred. + TranslationsRu({Map? overrides, PluralResolver? cardinalResolver, PluralResolver? ordinalResolver}) + : assert(overrides == null, 'Set "translation_overrides: true" in order to enable this feature.'), + $meta = TranslationMetadata( + locale: AppLocale.ru, + overrides: overrides ?? {}, + cardinalResolver: cardinalResolver, + ordinalResolver: ordinalResolver, + ) { + $meta.setFlatMapFunction(_flatMapFunction); + } + + /// Metadata for the translations of . + @override final TranslationMetadata $meta; + + /// Access flat map + @override dynamic operator[](String key) => $meta.getTranslation(key); + + late final TranslationsRu _root = this; // ignore: unused_field + + // Translations + @override late final _TranslationsAboutScreenRu AboutScreen = _TranslationsAboutScreenRu._(_root); + @override late final _TranslationsAddProfileByImportFromFileScreenRu AddProfileByImportFromFileScreen = _TranslationsAddProfileByImportFromFileScreenRu._(_root); + @override late final _TranslationsAddProfileByLinkOrContentScreenRu AddProfileByLinkOrContentScreen = _TranslationsAddProfileByLinkOrContentScreenRu._(_root); + @override late final _TranslationsAddProfileByScanQrcodeScanScreenRu AddProfileByScanQrcodeScanScreen = _TranslationsAddProfileByScanQrcodeScanScreenRu._(_root); + @override late final _TranslationsBackupAndSyncLanSyncScreenRu BackupAndSyncLanSyncScreen = _TranslationsBackupAndSyncLanSyncScreenRu._(_root); + @override late final _TranslationsBackupAndSyncWebdavScreenRu BackupAndSyncWebdavScreen = _TranslationsBackupAndSyncWebdavScreenRu._(_root); + @override late final _TranslationsDiversionGroupCustomEditScreenRu DiversionGroupCustomEditScreen = _TranslationsDiversionGroupCustomEditScreenRu._(_root); + @override late final _TranslationsDiversionRuleDetectScreenRu DiversionRuleDetectScreen = _TranslationsDiversionRuleDetectScreenRu._(_root); + @override late final _TranslationsDiversionRulesScreenRu DiversionRulesScreen = _TranslationsDiversionRulesScreenRu._(_root); + @override late final _TranslationsDnsSettingsScreenRu DnsSettingsScreen = _TranslationsDnsSettingsScreenRu._(_root); + @override late final _TranslationsFeedbackScreenRu FeedbackScreen = _TranslationsFeedbackScreenRu._(_root); + @override late final _TranslationsFileContentViewerScreenRu FileContentViewerScreen = _TranslationsFileContentViewerScreenRu._(_root); + @override late final _TranslationsHomeScreenRu HomeScreen = _TranslationsHomeScreenRu._(_root); + @override late final _TranslationsLaunchFailedScreenRu LaunchFailedScreen = _TranslationsLaunchFailedScreenRu._(_root); + @override late final _TranslationsMyProfilesEditScreenRu MyProfilesEditScreen = _TranslationsMyProfilesEditScreenRu._(_root); + @override late final _TranslationsMyProfilesMergeScreenRu MyProfilesMergeScreen = _TranslationsMyProfilesMergeScreenRu._(_root); + @override late final _TranslationsMyProfilesScreenRu MyProfilesScreen = _TranslationsMyProfilesScreenRu._(_root); + @override late final _TranslationsNetCheckScreenRu NetCheckScreen = _TranslationsNetCheckScreenRu._(_root); + @override late final _TranslationsNetConnectionsFilterScreenRu NetConnectionsFilterScreen = _TranslationsNetConnectionsFilterScreenRu._(_root); + @override late final _TranslationsNetConnectionsScreenRu NetConnectionsScreen = _TranslationsNetConnectionsScreenRu._(_root); + @override late final _TranslationsPerAppAndroidScreenRu PerAppAndroidScreen = _TranslationsPerAppAndroidScreenRu._(_root); + @override late final _TranslationsQrcodeScreenRu QrcodeScreen = _TranslationsQrcodeScreenRu._(_root); + @override late final _TranslationsRegionSettingsScreenRu RegionSettingsScreen = _TranslationsRegionSettingsScreenRu._(_root); + @override late final _TranslationsServerSelectScreenRu ServerSelectScreen = _TranslationsServerSelectScreenRu._(_root); + @override late final _TranslationsSettingsScreenRu SettingsScreen = _TranslationsSettingsScreenRu._(_root); + @override late final _TranslationsSpeedTestSettingsScreenRu SpeedTestSettingsScreen = _TranslationsSpeedTestSettingsScreenRu._(_root); + @override late final _TranslationsTextToQrCodeScreenRu TextToQrCodeScreen = _TranslationsTextToQrCodeScreenRu._(_root); + @override late final _TranslationsUserAgreementScreenRu UserAgreementScreen = _TranslationsUserAgreementScreenRu._(_root); + @override late final _TranslationsVersionUpdateScreenRu VersionUpdateScreen = _TranslationsVersionUpdateScreenRu._(_root); + @override late final _TranslationsCommonWidgetRu CommonWidget = _TranslationsCommonWidgetRu._(_root); + @override late final _TranslationsServerManagerRu ServerManager = _TranslationsServerManagerRu._(_root); + @override late final _TranslationsMainRu main = _TranslationsMainRu._(_root); + @override String get enable => 'Включить'; + @override String get disable => 'Запретить'; + @override String get filter => 'Фильтр'; + @override String get filterMethod => 'Метод фильтра'; + @override String get include => 'Включать'; + @override String get exclude => 'Исключать'; + @override String get all => 'Все'; + @override String get prefer => 'Приоритет'; + @override String get only => 'Только'; + @override String get open => 'Открыть'; + @override String get close => 'Закрыть'; + @override String get quit => 'Выйти'; + @override String get add => 'Добавить'; + @override String get remove => 'Удалить'; + @override String get edit => 'Редактировать'; + @override String get view => 'Просмотр'; + @override String get more => 'Больше'; + @override String get addProfile => 'Добавить профиль'; + @override String get addSuccess => 'Добавлено успешно'; + @override String addSuccessThen({required Object p}) => 'Конфигурация сгенерирована успешно. Для просмотра перейдите в [${p}]'; + @override String addFailed({required Object p}) => 'Ошибка при добавлении:${p}'; + @override String get removeConfirm => 'Подтверждаете удаление?'; + @override String get tips => 'Инфо'; + @override String get copy => 'Скопировать'; + @override String get ok => 'Ок'; + @override String get cancel => 'Закрыть'; + @override String get feedback => 'Обратная связь'; + @override String get faq => 'Часто задаваемые вопросы (FAQ)'; + @override String get download => 'Скачать'; + @override String get loading => 'Загрузка...'; + @override String updateFailed({required Object p}) => 'Не удалось обновить:${p}'; + @override String get days => 'дни'; + @override String get hours => 'часы'; + @override String get minutes => 'минуты'; + @override String get seconds => 'Второй'; + @override String get protocol => 'Протокол'; + @override String get search => 'Поиск'; + @override String get custom => 'Настроить самостоятельно'; + @override String get connect => 'Соединить'; + @override String get disconnect => 'Отключить'; + @override String get connected => 'Подключено'; + @override String get disconnected => 'Отключено'; + @override String get connecting => 'Подключение'; + @override String get connectTimeout => 'Таймаут при соединении'; + @override String get timeout => 'Тайм-аут'; + @override String get language => 'Язык'; + @override String get next => 'Дальше'; + @override String get done => 'Готово'; + @override String get apply => 'Применить'; + @override String get refresh => 'Обновить'; + @override String get retry => 'Хотите попробовать еще раз?'; + @override String get none => 'Ничего не делать'; + @override String get reset => 'Перезагрузить'; + @override String get submit => 'Отправить'; + @override String get account => 'Аккаунт'; + @override String get password => 'Пароль'; + @override String get required => 'Необходимо'; + @override String get diversion => 'Правила'; + @override String get diversionRules => 'Правила перенаправления'; + @override String get diversionRulesEnable => 'Включить правила перенаправления [ISP]'; + @override String get diversionCustomGroup => 'Личные правила'; + @override String get diversionCustomGroupPreset => 'Шаблоны личных правил'; + @override String get diversionCustomGroupPresetTips => 'Примечание. Включенные элементы будут добавлены в [Личные правила] и [Правила перенаправления].'; + @override String get diversionCustomGroupAddTips => 'Примечание. Возможно, вам придется вручную настроить порядок правил после их добавления, иначе добавленное перенаправление может работать не так, как ожидалось.'; + @override String get urlTestCustomGroup => 'Личная группа прокси-серверов'; + @override String get rulesetEnableTips => 'Совет: После включения опции перейдите в [Правила перенаправления] и установите их, иначе опция не будет действовать'; + @override String get ispUserAgentTips => '[ISP] будет доставлять различные типы данных о подписке на основе [UserAgent] в запросе [HTTP].'; + @override String get ispDiversionTips => 'Правила перенаправления, предоставляемые подписками [ISP] типа [V2Ray], не поддерживаются.'; + @override String get staticIP => 'Статический IP'; + @override String get other => 'Другой'; + @override String get dns => 'DNS'; + @override String get url => 'URL'; + @override String get isp => 'ISP'; + @override String get tls => 'TLS'; + @override String get userAgent => 'UserAgent'; + @override String get urlInvalid => 'Неверный URL'; + @override String get outboundActionCurrentSelected => 'Текущий сервер'; + @override String get outboundActionUrltest => 'Автовыбор сервера'; + @override String get outboundActionDirect => 'Напрямую'; + @override String get outboundActionBlock => 'Блокировать'; + @override String get routeFinal => 'Final'; + @override String get rulesetGeoSite => 'GeoSite'; + @override String get rulesetGeoIp => 'GeoIP'; + @override String get rulesetAcl => 'ACL'; + @override String get iCloud => 'iCloud'; + @override String get appleTV => 'Apple TV'; + @override String get webdav => 'Webdav'; + @override String get setting => 'Настройки'; + @override String get protocolSniff => 'Определение протокола'; + @override String get protocolSniffOverrideDestination => 'Обнаруженное имя домена перезаписывает целевой адрес подключения.'; + @override String get remark => 'Примечание'; + @override String get remarkCannotEmpty => 'Примечание не может быть пустым'; + @override String get remarkTooLong => 'Примечания до 32 символов'; + @override String get remarkExist => 'Примечание уже существует, используйте другое имя'; + @override String get domainSuffix => 'Суффикс доменного имени'; + @override String get domain => 'Имя домена'; + @override String get domainKeyword => 'Ключевые слова в имени домена'; + @override String get domainRegex => 'Регулярные выражения для имен доменов'; + @override String get ip => 'IP'; + @override String get port => 'Порт'; + @override String get appPackage => 'Имя пакета приложения'; + @override String get processName => 'Имя процесса'; + @override String get processPath => 'Путь к процессу'; + @override String get systemProxy => 'Системный прокси'; + @override String get netInterfaces => 'Сетевой интерфейс'; + @override String get netSpeed => 'Скорость'; + @override String get website => 'Веб-сайт'; + @override String get rule => 'Правила'; + @override String get global => 'Глобально'; + @override String get qrcode => 'QR-код'; + @override String get scanQrcode => 'Сканировать QR-код'; + @override String get scanResult => 'Результат сканирования'; + @override String get backupAndSync => 'Резервное копирование и синхронизация'; + @override String get importAndExport => 'Импорт и экспорт'; + @override String get import => 'Импорт'; + @override String get export => 'Экспорт'; + @override String get send => 'Передать'; + @override String get receive => 'Принять'; + @override String sendOrReceiveNotMatch({required Object p}) => 'Пожалуйста, используйте [${p}]'; + @override String get sendConfirm => 'Подтверждаете передачу?'; + @override String get termOfUse => 'Условия использования'; + @override String get privacyPolicy => 'Политика конфиденциальности'; + @override String get about => 'О Karing'; + @override String get name => 'Название'; + @override String get version => 'Версия'; + @override String get notice => 'Уведомления'; + @override String get sort => 'Отсортировать'; + @override String get novice => 'Режим новичка'; + @override String get recommended => 'Рекомендуемые'; + @override String innerError({required Object p}) => 'Внутренняя ошибка:${p}'; + @override String get logicOperation => 'Логическая опреация'; + @override String get share => 'Поделиться'; + @override String get candidateWord => 'Ключевые слова'; + @override String get keywordOrRegx => 'Ключевые слова/регулярные выражения'; + @override String get importFromClipboard => 'Импорт из буфера обмена'; + @override String get exportToClipboard => 'Экспорт в буфер обмена'; + @override String get server => 'Сервер'; + @override String get appleTVConnectTurnOfprivateDirect => 'Пожалуйста, сначала включите [Прямое подключение к частной сети]'; + @override String targetConnectFailed({required Object p}) => 'Не удалось подключиться к [${p}]. Убедитесь, что устройство находится в той же локальной сети, и включите [Прямое подключение к частной сети].'; + @override String get appleTVSync => 'Синхронизация текущей базовой конфигурации с Apple TV - Karing'; + @override String get appleTVSyncDone => 'Синхронизация завершена, перейдите в Apple TV — Karing, чтобы открыть/перезапустить соединение.'; + @override String get appleTVRemoveCoreConfig => 'Удаление Apple TV — базовая конфигурация Karing'; + @override String get appleTVRemoveCoreConfigDone => 'Apple TV — основной профиль Karing удален; VPN-сервис отключен;'; + @override String get appleTVUrlInvalid => 'Неверный URL-адрес. Откройте Apple TV — Karing, отсканируйте QR-код, отображаемый Karing.'; + @override String get remoteProfileEditConfirm => 'После обновления конфигурации изменения узла будут восстановлены. Продолжить?'; + @override String invalidFileType({required Object p}) => 'Неверный тип файла:${p}'; + @override String get mustBeValidHttpsURL => 'https URL должен быть действительным'; + @override String fileNotExistReinstall({required Object p}) => 'Файл отсутствует [${p}], пожалуйста, переустановите'; + @override String get latencyTest => 'Обнаружение задержки'; + @override String get latencyTestResolveIP => 'При ручном определении также анализируется экспортный IP-адрес.'; + @override String get uwpExemption => 'Исключение из изоляции сети UWP'; + @override String get removeBannerAds => 'Удалить рекламу'; + @override String get removeBannerAdsByReward => 'Посмотрите несколько секунд рекламы, и вы будете вознаграждены 7 днями без рекламы.'; + @override String get removeBannerAdsByRewardDone => 'Получил награду в течение 7 дней без рекламы'; + @override Map get locales => { + 'en': 'English', + 'zh-CN': '简体中文', + 'ar': 'عربي', + 'ru': 'Русский', + 'fa': 'فارسی', + }; +} + +// Path: AboutScreen +class _TranslationsAboutScreenRu implements TranslationsAboutScreenEn { + _TranslationsAboutScreenRu._(this._root); + + final TranslationsRu _root; // ignore: unused_field + + // Translations + @override String get installRefer => 'Ссылка на установку'; + @override String get versionChannel => 'Канал автоматического обновления'; + @override String get disableUAReport => 'Отключить аналитику'; + @override String get disableUAReportTip => 'Данные отчётов о поведении программы помогают нам улучшить её работу; версии младше основной автоматически отключают все отчеты (кроме [Запуска приложения]).'; + @override String get devOptions => 'Параметры разработчика'; + @override String get enableDebugLog => 'Включить debug-лог'; + @override String get viewFilsContent => 'Посмотреть файлы'; + @override String get enablePprof => 'Включить pprof'; + @override String get pprofPanel => 'pprof панель'; + @override String get openDir => 'Открыть каталог файлов'; + @override String get useOriginalSBProfile => 'Использовать исходную конфигурацию Sing-box'; +} + +// Path: AddProfileByImportFromFileScreen +class _TranslationsAddProfileByImportFromFileScreenRu implements TranslationsAddProfileByImportFromFileScreenEn { + _TranslationsAddProfileByImportFromFileScreenRu._(this._root); + + final TranslationsRu _root; // ignore: unused_field + + // Translations + @override String get title => 'Импорт файла конфигурации'; + @override String get chooseFile => 'Выбрать файл'; + @override String get configExist => 'Профиль уже существует. Пожалуйста, не добавляйте его повторно'; +} + +// Path: AddProfileByLinkOrContentScreen +class _TranslationsAddProfileByLinkOrContentScreenRu implements TranslationsAddProfileByLinkOrContentScreenEn { + _TranslationsAddProfileByLinkOrContentScreenRu._(this._root); + + final TranslationsRu _root; // ignore: unused_field + + // Translations + @override String get title => 'Добавление подписки'; + @override String get updateTimerInterval => 'Интервал обновления'; + @override String get updateTimerIntervalTips => 'Минимум: 5 м'; + @override String get profileLinkContent => 'Ссылка на подписку/содержание'; + @override String get profileLinkContentHit => 'Ссылка на подписку/содержание [обязательно] (Поддерживаются Clash, V2ray(c пакетом поддержки), Stash, Karing, Sing-box, Shadowsocks, Sub; Ссылка на конфигурацию).'; + @override String get subscriptionCannotEmpty => 'Ссылка на подписку не может быть пустой'; + @override String get configExist => 'Профиль уже существует. Пожалуйста, не добавляйте его повторно'; + @override String get invalidUrl => 'Ссылка на подписку слишком длинная'; + @override String addFailedFormatException({required Object p}) => 'Неправильный формат, исправьте его и добавьте еще раз:${p}'; + @override String addFailedThenDownloadAndImport({required Object p}) => 'Не удалось добавить: ${p}. Попробуйте изменить [UserAgent] и повторите попытку, или используйте собственный браузер устройства, чтобы открыть ссылку на конфигурацию и импортировать файл конфигурации, загруженный браузером, в это приложение.'; + @override String addFailedHandshakeException({required Object p}) => 'Не удалось добавить: ${p}, откройте агент или измените текущий узел агента и повторите попытку.'; +} + +// Path: AddProfileByScanQrcodeScanScreen +class _TranslationsAddProfileByScanQrcodeScanScreenRu implements TranslationsAddProfileByScanQrcodeScanScreenEn { + _TranslationsAddProfileByScanQrcodeScanScreenRu._(this._root); + + final TranslationsRu _root; // ignore: unused_field + + // Translations + @override String get copy => 'Скопировать ссылку'; + @override String get open => 'Открыть ссылку'; + @override String get requestCameraPermission => 'Пожалуйста, разрешите приложению доступ к камере'; + @override String get requestScreenAccess => 'Пожалуйста, перейдите в «Настройки системы» — «Конфиденциальность и безопасность» — «Запись экрана», чтобы добавить разрешения для этого приложения'; + @override String get screenshot => 'Скриншот'; + @override String get scanFromImage => 'Открыть'; + @override String get scanNoResult => 'Не удалось проанализировать изображение. Убедитесь, что снимок экрана представляет собой действительный QR-код.'; + @override String get scanEmptyResult => 'Пустой результат сканирования.'; + @override String scanException({required Object p}) => 'Не удалось проанализировать изображение. Убедитесь, что снимок экрана представляет собой действительный QR-код:${p}'; +} + +// Path: BackupAndSyncLanSyncScreen +class _TranslationsBackupAndSyncLanSyncScreenRu implements TranslationsBackupAndSyncLanSyncScreenEn { + _TranslationsBackupAndSyncLanSyncScreenRu._(this._root); + + final TranslationsRu _root; // ignore: unused_field + + // Translations + @override String get title => 'Синхронизация по локальной сети'; + @override String get lanSyncNotQuitTips => 'Не выходите из этого окна до завершения синхронизации.'; +} + +// Path: BackupAndSyncWebdavScreen +class _TranslationsBackupAndSyncWebdavScreenRu implements TranslationsBackupAndSyncWebdavScreenEn { + _TranslationsBackupAndSyncWebdavScreenRu._(this._root); + + final TranslationsRu _root; // ignore: unused_field + + // Translations + @override String get webdavServerUrl => 'Адрес сервера'; + @override String get webdavRequired => 'Не может быть пустым'; + @override String get webdavLoginFailed => 'Ошибка входа:'; + @override String get webdavListFailed => 'Не удалось получить список файлов:'; +} + +// Path: DiversionGroupCustomEditScreen +class _TranslationsDiversionGroupCustomEditScreenRu implements TranslationsDiversionGroupCustomEditScreenEn { + _TranslationsDiversionGroupCustomEditScreenRu._(this._root); + + final TranslationsRu _root; // ignore: unused_field + + // Translations + @override String invalidDomain({required Object p}) => 'Неверный [Domain]:${p}'; + @override String invalidIpCidr({required Object p}) => 'Неверный [IP Cidr]:${p}'; + @override String invalidPort({required Object p}) => 'Неверный [Port]:${p}'; + @override String invalidRuleSet({required Object p}) => 'Неверный [Rule Set]:${p}, URL-адрес должен быть действительным URL-адресом https двоичного файлом с расширением .srs/.json'; + @override String invalidRuleSetBuildIn({required Object p}) => 'Неверный [RuleSet(build-in)]:${p}, формат: geosite:xxx или geoip:xxx или acl:xxx, а xxx должно быть допустимым именем правила.'; + @override String get setDiversionRule => 'Совет: после сохранения перейдите в раздел [Правила перенаправления] и настройте их, иначе изменения не будут действовать.'; +} + +// Path: DiversionRuleDetectScreen +class _TranslationsDiversionRuleDetectScreenRu implements TranslationsDiversionRuleDetectScreenEn { + _TranslationsDiversionRuleDetectScreenRu._(this._root); + + final TranslationsRu _root; // ignore: unused_field + + // Translations + @override String get title => 'Тест правил перенаправления'; + @override String get detect => 'Тест'; + @override String get rule => 'Правило:'; + @override String get outbound => 'Прокси-сервер:'; +} + +// Path: DiversionRulesScreen +class _TranslationsDiversionRulesScreenRu implements TranslationsDiversionRulesScreenEn { + _TranslationsDiversionRulesScreenRu._(this._root); + + final TranslationsRu _root; // ignore: unused_field + + // Translations + @override String get diversionRulesMatchTips => 'Совет: Правила применяются по очереди сверху вниз. Если ни одно соответствие не обнаружено, то действует правило [Final]'; +} + +// Path: DnsSettingsScreen +class _TranslationsDnsSettingsScreenRu implements TranslationsDnsSettingsScreenEn { + _TranslationsDnsSettingsScreenRu._(this._root); + + final TranslationsRu _root; // ignore: unused_field + + // Translations + @override String get ispCanNotEmpty => 'ISP не может быть пустой'; + @override String get urlCanNotEmpty => 'URL не может быть пустой'; + @override String error({required Object p}) => 'Неподдерживаемый тип:${p}'; + @override String get dnsDesc => 'Первый столбец данных — это задержка запроса при прямом соединении;\nВторой столбец, если включено [[действующий поток] Разрешать DNS через прокси-сервер]: данные — это задержка запроса, пересылаемого через текущий прокси-сервер; Если выключено [[действующий поток] Разрешать DNS через прокси-сервер]: данные - это задержка запроса при прямом соединении.'; +} + +// Path: FeedbackScreen +class _TranslationsFeedbackScreenRu implements TranslationsFeedbackScreenEn { + _TranslationsFeedbackScreenRu._(this._root); + + final TranslationsRu _root; // ignore: unused_field + + // Translations + @override String get content => 'Содержание'; + @override String get contentHit => 'Не более 500 символов'; + @override String get contentCannotEmpty => 'Содержание не может быть пустым'; +} + +// Path: FileContentViewerScreen +class _TranslationsFileContentViewerScreenRu implements TranslationsFileContentViewerScreenEn { + _TranslationsFileContentViewerScreenRu._(this._root); + + final TranslationsRu _root; // ignore: unused_field + + // Translations + @override String get title => 'Просмотр содержимого файла'; + @override String get chooseFile => 'Выберите файл'; + @override String get clearFileContent => 'Вы уверены, что хотите очистить содержимое файла?'; + @override String get clearFileContentTips => 'Вы уверены, что хотите очистить содержимое файла профиля? Очистка файла профиля может привести к потере данных или некорректной работе приложения. Действуйте осторожно.'; +} + +// Path: HomeScreen +class _TranslationsHomeScreenRu implements TranslationsHomeScreenEn { + _TranslationsHomeScreenRu._(this._root); + + final TranslationsRu _root; // ignore: unused_field + + // Translations + @override String get toSelectServer => 'Выберите сервер'; + @override String get invalidServer => 'Не работает. Пожалуйста, выберите другой'; + @override String get disabledServer => 'Был отключен. Пожалуйста, выберите другой'; + @override String get expiredServer => 'Нет доступного сервера: возможно, профиль устарел или отключен'; + @override String systemProxyTips({required Object sp, required Object hp}) => 'socks:${sp},http(s):${hp}'; + @override String get trafficTotal => 'Трафик всего'; + @override String get trafficProxy => 'Трафик прокси'; + @override String get myLinkEmpty => 'Пожалуйста, настройте [Быструю ссылку] перед использованием'; + @override String get deviceNoSpace => 'Недостаточно места на диске'; + @override String tooMuchServers({required Object p, required Object p1}) => 'Слишком много прокси-серверов [${p}>${p1}], и соединение может оказаться невозможным из-за ограничений системной памяти'; +} + +// Path: LaunchFailedScreen +class _TranslationsLaunchFailedScreenRu implements TranslationsLaunchFailedScreenEn { + _TranslationsLaunchFailedScreenRu._(this._root); + + final TranslationsRu _root; // ignore: unused_field + + // Translations + @override String get invalidProcess => 'Не удалось запустить приложение [Неверное имя процесса], переустановите приложение в отдельную папку'; + @override String get invalidProfile => 'Не удалось запустить приложение [Не удалось получить доступ к профилю], переустановите приложение'; + @override String get invalidVersion => 'Не удалось запустить приложение [Неверная версия], переустановите приложение'; + @override String get systemVersionLow => 'Не удалось запустить приложение [Слишком низкая версия системы]'; + @override String get invalidInstallPath => 'Путь установки недействителен, переустановите его по допустимому пути'; +} + +// Path: MyProfilesEditScreen +class _TranslationsMyProfilesEditScreenRu implements TranslationsMyProfilesEditScreenEn { + _TranslationsMyProfilesEditScreenRu._(this._root); + + final TranslationsRu _root; // ignore: unused_field + + // Translations + @override String get title => 'Редактирование профилей'; + @override String get urlExist => 'URL-адрес уже существует, используйте другой URL-адрес'; + @override String get updateTimerInterval => 'Интервал обновления'; + @override String get updateTimerIntervalTips => 'Минимум: 5 м'; + @override String get reloadAfterProfileUpdate => 'Перезагрузить после обновления профиля'; + @override String get testLatencyAfterProfileUpdate => 'Начать тестирование задержек после обновления профиля'; + @override String get testLatencyAfterProfileUpdateTips => 'VPN необходимо подключить, и включить [Перезагрузить после обновления профиля]'; + @override String get testLatencyAutoRemove => 'Автоматически удалять серверы, не прошедшие тесты на задержку'; + @override String get testLatencyAutoRemoveTips => 'Попробуйте до 3 раз'; +} + +// Path: MyProfilesMergeScreen +class _TranslationsMyProfilesMergeScreenRu implements TranslationsMyProfilesMergeScreenEn { + _TranslationsMyProfilesMergeScreenRu._(this._root); + + final TranslationsRu _root; // ignore: unused_field + + // Translations + @override String get profilesMerge => 'Объединение профилей'; + @override String get profilesMergeTarget => 'Целевой профиль'; + @override String get profilesMergeSource => 'Профиль - источник'; + @override String get profilesMergeTips => 'Совет: Настройки перенаправления для профиля - источника будут удалены.'; +} + +// Path: MyProfilesScreen +class _TranslationsMyProfilesScreenRu implements TranslationsMyProfilesScreenEn { + _TranslationsMyProfilesScreenRu._(this._root); + + final TranslationsRu _root; // ignore: unused_field + + // Translations + @override String get title => 'Профили'; + @override String get atLeastOneEnable => 'Невозможно отключить, оставьте включенным хотя бы один профиль'; +} + +// Path: NetCheckScreen +class _TranslationsNetCheckScreenRu implements TranslationsNetCheckScreenEn { + _TranslationsNetCheckScreenRu._(this._root); + + final TranslationsRu _root; // ignore: unused_field + + // Translations + @override String get title => 'Диагностика сети'; + @override String get warn => 'Примечание. Из-за влияния сетевой среды и правил перенаправления результаты теста не полностью эквивалентны фактическим результатам.'; + @override String get check => 'Тест'; + @override String get invalidDomain => 'Неверное имя домена'; + @override String get connectivity => 'Подключение к сети'; + @override String connectivityTestIpv4AllFailed({required Object p}) => 'Ipv4 Тест подключения[${p}] неудачен'; + @override String get connectivityTestIpv4Ok => 'Ipv4 Соединение выполнено успешно'; + @override String connectivityTestIpv6AllFailed({required Object p}) => 'Ipv6 Тест подключения[${p}] неудачен. Возможно, ваша сеть не поддерживает ipv6.'; + @override String get connectivityTestIpv6Ok => 'Ipv6 Соединение выполнено успешно'; + @override String get connectivityTestOk => 'Сеть подключена к Интернету'; + @override String get connectivityTestFailed => 'Ваша сеть не подключена к Интернету'; + @override String get remoteRulesetsDownloadOk => 'Все успешно скачано'; + @override String get remoteRulesetsDownloadNotOk => 'Сбой загрузки'; + @override String get outbound => 'Прокси-сервер'; + @override String outboundOk({required Object p}) => '[${p}]Соединение установлено успешно'; + @override String outboundFailed({required Object p1, required Object p2}) => '[${p1}]Соединение не удалось\nошибка:[${p2}]'; + @override String get dnsServer => 'DNS сервер'; + @override String dnsOk({required Object p1, required Object p2, required Object p3, required Object p4}) => '[${p1}]DNS Разобрано успешно\nDNS правило:[${p2}]\nЗадержка:[${p3} ms]\nадрес:[${p4}]'; + @override String dnsFailed({required Object p1, required Object p2, required Object p3}) => '[${p1}]DNS Не удалось выполнить синтаксический анализ\n правило:[${p2}]\nошибка:[${p3}]'; + @override String get host => 'HTTP соединение'; + @override String hostConnection({required Object p1, required Object p2, required Object p3}) => '[${p1}]\nПравила перенаправления:[${p2}]\nПрокси-сервер:[${p3}]'; + @override String get hostConnectionOk => 'Соединение установлено успешно'; + @override String hostConnectionFailed({required Object p}) => 'Соединение не удалось:[${p}]'; +} + +// Path: NetConnectionsFilterScreen +class _TranslationsNetConnectionsFilterScreenRu implements TranslationsNetConnectionsFilterScreenEn { + _TranslationsNetConnectionsFilterScreenRu._(this._root); + + final TranslationsRu _root; // ignore: unused_field + + // Translations + @override String get title => 'Фильтр соединений'; + @override String get hostIp => 'Domain/IP'; + @override String get app => 'Приложение'; + @override String get rule => 'Правило'; + @override String get chain => 'Исходящий'; +} + +// Path: NetConnectionsScreen +class _TranslationsNetConnectionsScreenRu implements TranslationsNetConnectionsScreenEn { + _TranslationsNetConnectionsScreenRu._(this._root); + + final TranslationsRu _root; // ignore: unused_field + + // Translations + @override String get title => 'Соединения'; + @override String get copyAsCSV => 'Скопировано в CSV формате'; + @override String get selectType => 'Выберите тип перенаправления'; +} + +// Path: PerAppAndroidScreen +class _TranslationsPerAppAndroidScreenRu implements TranslationsPerAppAndroidScreenEn { + _TranslationsPerAppAndroidScreenRu._(this._root); + + final TranslationsRu _root; // ignore: unused_field + + // Translations + @override String get title => 'Проксируемые приложения'; + @override String get whiteListMode => 'Режим белого списка'; + @override String get whiteListModeTip => 'Если включено: перенаправляются через прокси-сервер только те приложения, которые были отмечены. Если выключено: перенаправляются через прокси-сервер только те приложения, которые не были отмечены.'; + @override String get hideSystemApp => 'Скрыть системные приложения'; + @override String get hideAppIcon => 'Скрыть значок приложения'; + @override String get enableAppQueryPermission => 'Включать разрешения [на запросы списка приложений]'; +} + +// Path: QrcodeScreen +class _TranslationsQrcodeScreenRu implements TranslationsQrcodeScreenEn { + _TranslationsQrcodeScreenRu._(this._root); + + final TranslationsRu _root; // ignore: unused_field + + // Translations + @override String get tooLong => 'Слишком большой текст для отображения'; + @override String get copy => 'Скопировать ссылку'; + @override String get open => 'Открыть ссылку'; + @override String get share => 'Поделиться ссылкой'; + @override String get shareImage => 'Поделиться QR-кодом'; +} + +// Path: RegionSettingsScreen +class _TranslationsRegionSettingsScreenRu implements TranslationsRegionSettingsScreenEn { + _TranslationsRegionSettingsScreenRu._(this._root); + + final TranslationsRu _root; // ignore: unused_field + + // Translations + @override String get title => 'Страна или регион'; + @override String get Regions => 'Совет: Пожалуйста, правильно укажите текущую страну или регион. В противном случае это может вызвать проблемы с перенаправлением в сети'; +} + +// Path: ServerSelectScreen +class _TranslationsServerSelectScreenRu implements TranslationsServerSelectScreenEn { + _TranslationsServerSelectScreenRu._(this._root); + + final TranslationsRu _root; // ignore: unused_field + + // Translations + @override String get title => 'Выбор сервера'; + @override String get autoSelectServer => 'Автовыбор сервера с наименьшей задержкой'; + @override String get recentUse => 'Недавно использованные'; + @override String get myFav => 'Мои избранные'; + @override String selectLocal({required Object p}) => 'Выбранный сервер является локальным, и может работать неправильно:${p}'; + @override String get selectRequireEnableIPv6 => 'Выбранный сервер имеет адрес IPv6 и требует [Включить IPv6]'; + @override String get selectDisabled => 'Сервер отключен'; + @override String get error404 => 'При измерении задержки произошла ошибка. Проверьте, существует ли профиль с таким содержимым.'; +} + +// Path: SettingsScreen +class _TranslationsSettingsScreenRu implements TranslationsSettingsScreenEn { + _TranslationsSettingsScreenRu._(this._root); + + final TranslationsRu _root; // ignore: unused_field + + // Translations + @override String ispFaq({required Object p}) => 'FAQ[${p}]'; + @override String cleanISP({required Object p}) => 'Очистить ISP[${p}]'; + @override String get openISP => 'Открыть ссылку на провайдера'; + @override String get cleanISPNoParam => 'Очистить информацию об интернет-провайдере'; + @override String get getTranffic => 'Получить трафик'; + @override String get tutorial => 'Руководство'; + @override String get commonlyUsedRulesets => 'Коллекция наборов правил'; + @override String get howToRemoveAds => 'Как удалить рекламу'; + @override String get htmlBoard => 'Веб-панель'; + @override String get dnsLeakDetection => 'Тест утечки DNS'; + @override String get speedTest => 'Тест скорости'; + @override String get downloadProfilePreferProxy => 'Настройка приоритетного выбора прокси-сервера'; + @override String get downloadProfilePreferProxyTips => 'Если подключение установлено, профиль вначале будет загружен через подключенный прокси-сервер'; + @override String get rulesetDirectDownlad => 'Правила прямой загрузки'; + @override String get hideUnusedDiversionGroup => 'Скрыть неактивные правила перенаправления'; + @override String get disableISPDiversionGroup => 'Отключить правила перенаправления ISP'; + @override String get portSetting => 'Используемые порты'; + @override String get portSettingRule => 'Действуют все правила'; + @override String get portSettingDirectAll => 'Всё подключено напрямую'; + @override String get portSettingProxyAll => 'Всё идёт через прокси'; + @override String get portSettingControl => 'Управление и синхронизация'; + @override String get portSettingCluster => 'Кластерный сервис'; + @override String get modifyPort => 'Изменить порт'; + @override String get modifyPortOccupied => 'Порт занят, используйте другой порт'; + @override String get ipStrategyTips => 'Перед включением убедитесь, что ваша сеть поддерживает IPv6, в противном случае нормальный доступ к части трафика будет невозможен'; + @override String get tunAppendHttpProxy => 'Подключите HTTP-прокси к VPN'; + @override String get tunAppendHttpProxyTips => 'Некоторые приложения будут обходить устройство виртуальной сетевой карты и напрямую подключаться к HTTP-прокси.'; + @override String get tlsInsecureEnable => 'Пропустить проверку сертификата'; + @override String get tlsFragmentEnable => 'Включить фрагментацию TLS'; + @override String get tlsFragmentSize => 'Размер фрагмента TLS'; + @override String get tlsFragmentSleep => 'Длина фрагмента паузы TLS'; + @override String get tlsMixedCaseSNIEnable => 'Включить гибридный SNI TLS'; + @override String get tlsPaddingEnable => 'Включить заполнение TLS'; + @override String get tlsPaddingSize => 'Размер заполнения TLS'; + @override String get dnsEnableRule => 'Включить правила DNS'; + @override String get dnsEnableFakeIp => 'Включить FakeIP'; + @override String get dnsEnableClientSubnet => 'Включить ECS'; + @override String get dnsEnableProxyResolveByProxy => '[действующий поток] Разрешать DNS через прокси-сервер'; + @override String get dnsEnableFinalResolveByProxy => '[final] Разрешать DNS через прокси-сервер'; + @override String get dnsTestDomain => 'Тестовое доменное имя'; + @override String get dnsTestDomainInvalid => 'Неверное доменное имя'; + @override String get dnsTypeOutbound => 'Прокси-сервер'; + @override String get dnsTypeDirect => 'Прямой поток'; + @override String get dnsTypeProxy => 'Действующий поток'; + @override String get dnsTypeResolver => 'DNS-сервер'; + @override String get dnsEnableRuleTips => 'После включения, доменное имя выберет соответствующий DNS-сервер для разрешения в соответствии с правилами перенаправления.'; + @override String get dnsEnableFakeIpTips => 'После включения FakeIP, если VPN-соединение отключено, возможно, потребуется перезапустить приложение, эту функцию необходимо включить [Режим TUN];'; + @override String get dnsTypeOutboundTips => 'Для разрешения доменных имен прокси-сервера рекомендуется использовать безопасный DNS'; + @override String get dnsTypeDirectTips => 'Разрешение доменных имен для прямого потока'; + @override String get dnsTypeProxyTips => 'Разрешение доменных имен для действующего потока'; + @override String get dnsTypeResolverTips => 'Разрешение доменных имен для DNS-серверов'; + @override String get dnsTypeFinalTips => 'Разрешение доменных имен для потока Final'; + @override String get dnsAutoSetServer => 'Автоматически настроить сервер'; + @override String get dnsResetServer => 'Сбросить сервер'; + @override String get inboundDomainResolve => 'Разрешение входящих доменных имен'; + @override String get privateDirect => 'Прямое подключение к частной сети'; + @override String inboundDomainResolveTips({required Object p}) => 'Некоторые доменные имена без настроенных правил переадресации необходимо разрешить, прежде чем они смогут соответствовать правилам переадресации на основе IP; эта функция влияет на входящие запросы к порту прокси [${p}]'; + @override String get useRomoteRes => 'Использовать удаленные ресурсы'; + @override String get autoSelect => 'Автовыбор'; + @override String get autoSelectServerIgnorePerProxyServer => 'Игнорировать прокси-сервер [передний прокси]'; + @override String get autoSelectServerInterval => 'Интервал проверок задержки'; + @override String get autoSelectServerReTestIfNetworkUpdate => 'Перетестировать после смены сети'; + @override String get autoSelectServerIntervalTips => 'Чем короче временной интервал, тем чаще обновляются данные о задержке сервера. Но это потребует больше ресурсов и энергии'; + @override String get autoSelectServerFavFirst => 'Приоритетно [Мои избранные]'; + @override String get autoSelectServerUpdateCurrentServerAfterManualUrltest => 'Обновить текущий сервер после измерения задержки вручную'; + @override String get autoSelectServerFavFirstTips => 'Если список [Мои избранные] не пуст, то будут использоваться серверы из [Мои избранные]'; + @override String get autoSelectServerFilter => 'Отфильтровать сервера'; + @override String autoSelectServerFilterTips({required Object p}) => 'Ошибки превышения задержки сервера будут отфильтрованы; если после фильтрации ни один сервер не будет доступен, вместо него будут использоваться первые [${p}] серверы'; + @override String get autoSelectServerLimitedNum => 'Максимальное количество серверов'; + @override String get autoSelectServerLimitedNumTips => 'Серверы, превышающие это число, будут отфильтрованы.'; + @override String get numInvalid => 'Неправильный номер'; + @override String get hideInvalidServer => 'Скрыть нерабочие серверы'; + @override String get sortServer => 'Сортировка серверов'; + @override String get sortServerTips => 'Сортировать по задержке от низкой к высокой'; + @override String get selectServerHideRecommand => 'Скрыть [Рекомендуемые]'; + @override String get selectServerHideRecent => 'Скрыть [Недавно использованные]'; + @override String get selectServerHideFav => 'Скрыть [Мои избранные]'; + @override String get homeScreen => 'Настройка главного экрана'; + @override String get theme => 'Тема'; + @override String get myLink => 'Быстрая ссылка'; + @override String get myLinkInvalid => 'Неверный URL'; + @override String get autoConnectAfterLaunch => 'Автоматическое подключение после запуска'; + @override String get hideAfterLaunch => 'Скрыть окно после запуска'; + @override String get autoSetSystemProxy => 'Установить системный прокси после подключения'; + @override String get disconnectWhenQuit => 'Отключаться при выходе из приложения'; + @override String get allowBypass => 'Разрешить приложениям обходить VPN'; + @override String get importSuccess => 'Импорт выполнен успешно'; + @override String get rewriteConfirm => 'Этот файл перезапишет существующую локальную конфигурацию. Продолжить?'; + @override String get networkShare => 'Общий доступ к сети'; + @override String get frontProxy => 'Цепочка прокси'; + @override String frontProxyTips({required Object p}) => 'Запрос -> Фронт-прокси ->[Цепочка прокси-серверов в порядке cверху вниз]-Выходной прокси [${p}] - Целевой сервер'; + @override String get allowOtherHostsConnect => 'Разрешить подключение по локальной сети'; + @override String allowOtherHostsConnectTips({required Object sp, required Object hp}) => 'socks:${sp},http(s):${hp}'; + @override String get tunAutoRoute => 'Auto Route'; + @override String get tunStrictRoute => 'Strict Route'; + @override String get tunStrictRouteTips => 'Если после включения общего доступа другие люди не смогут получить доступ к этому устройству, попробуйте отключить этот переключатель.'; + @override String get enableCluster => 'Включить кластер прокси Socks/Http'; + @override String get clusterAllowOtherHostsConnect => 'Разрешить подключение по локальной сети к кластеру'; + @override String clusterAllowOtherHostsConnectTips({required Object ip, required Object port}) => 'http://${ip}:${port}/get_proxies'; + @override String get clusterAuth => 'Аутентификация прокси-кластера'; + @override String get tunMode => 'Режим TUN'; + @override String get tunModeTips => 'В режиме TUN весь трафик системы будет перенаправлен через соединение [В этом режиме вы можете оставить системный прокси отключенным]'; + @override String get tunModeRunAsAdmin => 'Для режима TUN требуются права администратора. Перезапустите приложение от имени администратора'; + @override String get tunStack => 'Stack'; + @override String get launchAtStartup => 'Запуск при включении'; + @override String get quitWhenSwitchSystemUser => 'Выйти из приложения при переключении пользователя'; + @override String get handleScheme => 'Схемы системного вызова'; + @override String get portableMode => 'Портативный режим'; + @override String get portableModeDisableTips => 'Если вам нужно выйти из портативного режима, выйдите из [karing] и вручную удалите папку [profiles] в том же каталоге, что и [karing.exe]'; + @override String get handleKaringScheme => 'Вызов karing://[параметры]'; + @override String get handleClashScheme => 'Вызов clash://[параметры]'; + @override String get handleSingboxScheme => 'Вызов sing-box://[параметры]'; + @override String get alwayOnVPN => 'всегда открытое соединение'; + @override String get removeSystemVPNConfig => 'Удалить профиль VPN'; + @override String get timeConnectOrDisconnect => 'Запланированное подключение/отключение'; + @override String get timeConnectOrDisconnectTips => 'Чтобы это заработало, необходимо подключить VPN; после его подключения [автоматическое засыпание] будет отключено'; + @override String timeConnectAndDisconnectInterval({required Object p}) => 'Интервал подключения/отключения не может быть меньше ${p} минут.'; + @override String get disableFontScaler => 'Отключить масштабирование шрифта'; + @override String get autoOrientation => 'Следовать за поворотом экрана'; + @override String get restartTakesEffect => 'Требуется перезапуск'; + @override String get resetSettings => 'Сброс настроек'; + @override String get cleanCache => 'Очистка кэша'; + @override String get cleanCacheDone => 'Очистка завершена'; + @override String get appleTestFlight => 'Apple TestFlight'; + @override String get appleAppStore => 'Apple AppStore'; + @override String hasNewVersion({required Object p}) => 'Обновить версию ${p}'; + @override String get follow => 'Подписаться на нас'; + @override String get contactUs => 'Связаться с нами'; + @override String get rateInApp => 'Оценить нас'; + @override String get rateInAppStore => 'Оценить нас в App Store'; +} + +// Path: SpeedTestSettingsScreen +class _TranslationsSpeedTestSettingsScreenRu implements TranslationsSpeedTestSettingsScreenEn { + _TranslationsSpeedTestSettingsScreenRu._(this._root); + + final TranslationsRu _root; // ignore: unused_field + + // Translations + @override String get title => 'URL-адрес теста скорости'; +} + +// Path: TextToQrCodeScreen +class _TranslationsTextToQrCodeScreenRu implements TranslationsTextToQrCodeScreenEn { + _TranslationsTextToQrCodeScreenRu._(this._root); + + final TranslationsRu _root; // ignore: unused_field + + // Translations + @override String get title => 'Преобразование текста в QR-код'; + @override String get convert => 'Конвертировать'; +} + +// Path: UserAgreementScreen +class _TranslationsUserAgreementScreenRu implements TranslationsUserAgreementScreenEn { + _TranslationsUserAgreementScreenRu._(this._root); + + final TranslationsRu _root; // ignore: unused_field + + // Translations + @override String get privacyFirst => 'Ваша конфиденциальность превыше всего'; + @override String get agreeAndContinue => 'Принять и продолжить'; +} + +// Path: VersionUpdateScreen +class _TranslationsVersionUpdateScreenRu implements TranslationsVersionUpdateScreenEn { + _TranslationsVersionUpdateScreenRu._(this._root); + + final TranslationsRu _root; // ignore: unused_field + + // Translations + @override String versionReady({required Object p}) => 'Новая версия [${p}] доступна'; + @override String get update => 'Перезапустить'; + @override String get cancel => 'Не сейчас'; +} + +// Path: CommonWidget +class _TranslationsCommonWidgetRu implements TranslationsCommonWidgetEn { + _TranslationsCommonWidgetRu._(this._root); + + final TranslationsRu _root; // ignore: unused_field + + // Translations + @override String get diableAlwayOnVPN => 'Если параметр [VPN всегда включен] включен, отключите его и попробуйте подключиться еще раз'; + @override String get resetPort => 'Пожалуйста, измените порт на другой доступный порт или закройте приложение, занимающее порт.'; +} + +// Path: ServerManager +class _TranslationsServerManagerRu implements TranslationsServerManagerEn { + _TranslationsServerManagerRu._(this._root); + + final TranslationsRu _root; // ignore: unused_field + + // Translations + @override String get noServerAvaliable => 'Нет доступных серверов, убедитесь что подписка или файл профиля корректен. Если ваша конфигурация взята из GitHub, получите адрес ссылки, нажав кнопку [Raw] на странице.'; + @override String get filePathCannotEmpty => 'Путь к файлу не может быть пустым'; + @override String fileNotExist({required Object p}) => 'Файла не существует:${p}'; + @override String get urlCannotEmpty => 'Ссылка не может быть пустой'; + @override String get invalidUrl => 'Некорректная ссылка на подписку'; + @override String get parseFailed => 'Получение подписки не удалось'; +} + +// Path: main +class _TranslationsMainRu implements TranslationsMainEn { + _TranslationsMainRu._(this._root); + + final TranslationsRu _root; // ignore: unused_field + + // Translations + @override late final _TranslationsMainTrayRu tray = _TranslationsMainTrayRu._(_root); +} + +// Path: main.tray +class _TranslationsMainTrayRu implements TranslationsMainTrayEn { + _TranslationsMainTrayRu._(this._root); + + final TranslationsRu _root; // ignore: unused_field + + // Translations + @override String get menuOpen => ' Открыть '; + @override String get menuExit => ' Выйти '; +} + +/// Flat map(s) containing all translations. +/// Only for edge cases! For simple maps, use the map function of this library. +extension on TranslationsRu { + dynamic _flatMapFunction(String path) { + switch (path) { + case 'AboutScreen.installRefer': return 'Ссылка на установку'; + case 'AboutScreen.versionChannel': return 'Канал автоматического обновления'; + case 'AboutScreen.disableUAReport': return 'Отключить аналитику'; + case 'AboutScreen.disableUAReportTip': return 'Данные отчётов о поведении программы помогают нам улучшить её работу; версии младше основной автоматически отключают все отчеты (кроме [Запуска приложения]).'; + case 'AboutScreen.devOptions': return 'Параметры разработчика'; + case 'AboutScreen.enableDebugLog': return 'Включить debug-лог'; + case 'AboutScreen.viewFilsContent': return 'Посмотреть файлы'; + case 'AboutScreen.enablePprof': return 'Включить pprof'; + case 'AboutScreen.pprofPanel': return 'pprof панель'; + case 'AboutScreen.openDir': return 'Открыть каталог файлов'; + case 'AboutScreen.useOriginalSBProfile': return 'Использовать исходную конфигурацию Sing-box'; + case 'AddProfileByImportFromFileScreen.title': return 'Импорт файла конфигурации'; + case 'AddProfileByImportFromFileScreen.chooseFile': return 'Выбрать файл'; + case 'AddProfileByImportFromFileScreen.configExist': return 'Профиль уже существует. Пожалуйста, не добавляйте его повторно'; + case 'AddProfileByLinkOrContentScreen.title': return 'Добавление подписки'; + case 'AddProfileByLinkOrContentScreen.updateTimerInterval': return 'Интервал обновления'; + case 'AddProfileByLinkOrContentScreen.updateTimerIntervalTips': return 'Минимум: 5 м'; + case 'AddProfileByLinkOrContentScreen.profileLinkContent': return 'Ссылка на подписку/содержание'; + case 'AddProfileByLinkOrContentScreen.profileLinkContentHit': return 'Ссылка на подписку/содержание [обязательно] (Поддерживаются Clash, V2ray(c пакетом поддержки), Stash, Karing, Sing-box, Shadowsocks, Sub; Ссылка на конфигурацию).'; + case 'AddProfileByLinkOrContentScreen.subscriptionCannotEmpty': return 'Ссылка на подписку не может быть пустой'; + case 'AddProfileByLinkOrContentScreen.configExist': return 'Профиль уже существует. Пожалуйста, не добавляйте его повторно'; + case 'AddProfileByLinkOrContentScreen.invalidUrl': return 'Ссылка на подписку слишком длинная'; + case 'AddProfileByLinkOrContentScreen.addFailedFormatException': return ({required Object p}) => 'Неправильный формат, исправьте его и добавьте еще раз:${p}'; + case 'AddProfileByLinkOrContentScreen.addFailedThenDownloadAndImport': return ({required Object p}) => 'Не удалось добавить: ${p}. Попробуйте изменить [UserAgent] и повторите попытку, или используйте собственный браузер устройства, чтобы открыть ссылку на конфигурацию и импортировать файл конфигурации, загруженный браузером, в это приложение.'; + case 'AddProfileByLinkOrContentScreen.addFailedHandshakeException': return ({required Object p}) => 'Не удалось добавить: ${p}, откройте агент или измените текущий узел агента и повторите попытку.'; + case 'AddProfileByScanQrcodeScanScreen.copy': return 'Скопировать ссылку'; + case 'AddProfileByScanQrcodeScanScreen.open': return 'Открыть ссылку'; + case 'AddProfileByScanQrcodeScanScreen.requestCameraPermission': return 'Пожалуйста, разрешите приложению доступ к камере'; + case 'AddProfileByScanQrcodeScanScreen.requestScreenAccess': return 'Пожалуйста, перейдите в «Настройки системы» — «Конфиденциальность и безопасность» — «Запись экрана», чтобы добавить разрешения для этого приложения'; + case 'AddProfileByScanQrcodeScanScreen.screenshot': return 'Скриншот'; + case 'AddProfileByScanQrcodeScanScreen.scanFromImage': return 'Открыть'; + case 'AddProfileByScanQrcodeScanScreen.scanNoResult': return 'Не удалось проанализировать изображение. Убедитесь, что снимок экрана представляет собой действительный QR-код.'; + case 'AddProfileByScanQrcodeScanScreen.scanEmptyResult': return 'Пустой результат сканирования.'; + case 'AddProfileByScanQrcodeScanScreen.scanException': return ({required Object p}) => 'Не удалось проанализировать изображение. Убедитесь, что снимок экрана представляет собой действительный QR-код:${p}'; + case 'BackupAndSyncLanSyncScreen.title': return 'Синхронизация по локальной сети'; + case 'BackupAndSyncLanSyncScreen.lanSyncNotQuitTips': return 'Не выходите из этого окна до завершения синхронизации.'; + case 'BackupAndSyncWebdavScreen.webdavServerUrl': return 'Адрес сервера'; + case 'BackupAndSyncWebdavScreen.webdavRequired': return 'Не может быть пустым'; + case 'BackupAndSyncWebdavScreen.webdavLoginFailed': return 'Ошибка входа:'; + case 'BackupAndSyncWebdavScreen.webdavListFailed': return 'Не удалось получить список файлов:'; + case 'DiversionGroupCustomEditScreen.invalidDomain': return ({required Object p}) => 'Неверный [Domain]:${p}'; + case 'DiversionGroupCustomEditScreen.invalidIpCidr': return ({required Object p}) => 'Неверный [IP Cidr]:${p}'; + case 'DiversionGroupCustomEditScreen.invalidPort': return ({required Object p}) => 'Неверный [Port]:${p}'; + case 'DiversionGroupCustomEditScreen.invalidRuleSet': return ({required Object p}) => 'Неверный [Rule Set]:${p}, URL-адрес должен быть действительным URL-адресом https двоичного файлом с расширением .srs/.json'; + case 'DiversionGroupCustomEditScreen.invalidRuleSetBuildIn': return ({required Object p}) => 'Неверный [RuleSet(build-in)]:${p}, формат: geosite:xxx или geoip:xxx или acl:xxx, а xxx должно быть допустимым именем правила.'; + case 'DiversionGroupCustomEditScreen.setDiversionRule': return 'Совет: после сохранения перейдите в раздел [Правила перенаправления] и настройте их, иначе изменения не будут действовать.'; + case 'DiversionRuleDetectScreen.title': return 'Тест правил перенаправления'; + case 'DiversionRuleDetectScreen.detect': return 'Тест'; + case 'DiversionRuleDetectScreen.rule': return 'Правило:'; + case 'DiversionRuleDetectScreen.outbound': return 'Прокси-сервер:'; + case 'DiversionRulesScreen.diversionRulesMatchTips': return 'Совет: Правила применяются по очереди сверху вниз. Если ни одно соответствие не обнаружено, то действует правило [Final]'; + case 'DnsSettingsScreen.ispCanNotEmpty': return 'ISP не может быть пустой'; + case 'DnsSettingsScreen.urlCanNotEmpty': return 'URL не может быть пустой'; + case 'DnsSettingsScreen.error': return ({required Object p}) => 'Неподдерживаемый тип:${p}'; + case 'DnsSettingsScreen.dnsDesc': return 'Первый столбец данных — это задержка запроса при прямом соединении;\nВторой столбец, если включено [[действующий поток] Разрешать DNS через прокси-сервер]: данные — это задержка запроса, пересылаемого через текущий прокси-сервер; Если выключено [[действующий поток] Разрешать DNS через прокси-сервер]: данные - это задержка запроса при прямом соединении.'; + case 'FeedbackScreen.content': return 'Содержание'; + case 'FeedbackScreen.contentHit': return 'Не более 500 символов'; + case 'FeedbackScreen.contentCannotEmpty': return 'Содержание не может быть пустым'; + case 'FileContentViewerScreen.title': return 'Просмотр содержимого файла'; + case 'FileContentViewerScreen.chooseFile': return 'Выберите файл'; + case 'FileContentViewerScreen.clearFileContent': return 'Вы уверены, что хотите очистить содержимое файла?'; + case 'FileContentViewerScreen.clearFileContentTips': return 'Вы уверены, что хотите очистить содержимое файла профиля? Очистка файла профиля может привести к потере данных или некорректной работе приложения. Действуйте осторожно.'; + case 'HomeScreen.toSelectServer': return 'Выберите сервер'; + case 'HomeScreen.invalidServer': return 'Не работает. Пожалуйста, выберите другой'; + case 'HomeScreen.disabledServer': return 'Был отключен. Пожалуйста, выберите другой'; + case 'HomeScreen.expiredServer': return 'Нет доступного сервера: возможно, профиль устарел или отключен'; + case 'HomeScreen.systemProxyTips': return ({required Object sp, required Object hp}) => 'socks:${sp},http(s):${hp}'; + case 'HomeScreen.trafficTotal': return 'Трафик всего'; + case 'HomeScreen.trafficProxy': return 'Трафик прокси'; + case 'HomeScreen.myLinkEmpty': return 'Пожалуйста, настройте [Быструю ссылку] перед использованием'; + case 'HomeScreen.deviceNoSpace': return 'Недостаточно места на диске'; + case 'HomeScreen.tooMuchServers': return ({required Object p, required Object p1}) => 'Слишком много прокси-серверов [${p}>${p1}], и соединение может оказаться невозможным из-за ограничений системной памяти'; + case 'LaunchFailedScreen.invalidProcess': return 'Не удалось запустить приложение [Неверное имя процесса], переустановите приложение в отдельную папку'; + case 'LaunchFailedScreen.invalidProfile': return 'Не удалось запустить приложение [Не удалось получить доступ к профилю], переустановите приложение'; + case 'LaunchFailedScreen.invalidVersion': return 'Не удалось запустить приложение [Неверная версия], переустановите приложение'; + case 'LaunchFailedScreen.systemVersionLow': return 'Не удалось запустить приложение [Слишком низкая версия системы]'; + case 'LaunchFailedScreen.invalidInstallPath': return 'Путь установки недействителен, переустановите его по допустимому пути'; + case 'MyProfilesEditScreen.title': return 'Редактирование профилей'; + case 'MyProfilesEditScreen.urlExist': return 'URL-адрес уже существует, используйте другой URL-адрес'; + case 'MyProfilesEditScreen.updateTimerInterval': return 'Интервал обновления'; + case 'MyProfilesEditScreen.updateTimerIntervalTips': return 'Минимум: 5 м'; + case 'MyProfilesEditScreen.reloadAfterProfileUpdate': return 'Перезагрузить после обновления профиля'; + case 'MyProfilesEditScreen.testLatencyAfterProfileUpdate': return 'Начать тестирование задержек после обновления профиля'; + case 'MyProfilesEditScreen.testLatencyAfterProfileUpdateTips': return 'VPN необходимо подключить, и включить [Перезагрузить после обновления профиля]'; + case 'MyProfilesEditScreen.testLatencyAutoRemove': return 'Автоматически удалять серверы, не прошедшие тесты на задержку'; + case 'MyProfilesEditScreen.testLatencyAutoRemoveTips': return 'Попробуйте до 3 раз'; + case 'MyProfilesMergeScreen.profilesMerge': return 'Объединение профилей'; + case 'MyProfilesMergeScreen.profilesMergeTarget': return 'Целевой профиль'; + case 'MyProfilesMergeScreen.profilesMergeSource': return 'Профиль - источник'; + case 'MyProfilesMergeScreen.profilesMergeTips': return 'Совет: Настройки перенаправления для профиля - источника будут удалены.'; + case 'MyProfilesScreen.title': return 'Профили'; + case 'MyProfilesScreen.atLeastOneEnable': return 'Невозможно отключить, оставьте включенным хотя бы один профиль'; + case 'NetCheckScreen.title': return 'Диагностика сети'; + case 'NetCheckScreen.warn': return 'Примечание. Из-за влияния сетевой среды и правил перенаправления результаты теста не полностью эквивалентны фактическим результатам.'; + case 'NetCheckScreen.check': return 'Тест'; + case 'NetCheckScreen.invalidDomain': return 'Неверное имя домена'; + case 'NetCheckScreen.connectivity': return 'Подключение к сети'; + case 'NetCheckScreen.connectivityTestIpv4AllFailed': return ({required Object p}) => 'Ipv4 Тест подключения[${p}] неудачен'; + case 'NetCheckScreen.connectivityTestIpv4Ok': return 'Ipv4 Соединение выполнено успешно'; + case 'NetCheckScreen.connectivityTestIpv6AllFailed': return ({required Object p}) => 'Ipv6 Тест подключения[${p}] неудачен. Возможно, ваша сеть не поддерживает ipv6.'; + case 'NetCheckScreen.connectivityTestIpv6Ok': return 'Ipv6 Соединение выполнено успешно'; + case 'NetCheckScreen.connectivityTestOk': return 'Сеть подключена к Интернету'; + case 'NetCheckScreen.connectivityTestFailed': return 'Ваша сеть не подключена к Интернету'; + case 'NetCheckScreen.remoteRulesetsDownloadOk': return 'Все успешно скачано'; + case 'NetCheckScreen.remoteRulesetsDownloadNotOk': return 'Сбой загрузки'; + case 'NetCheckScreen.outbound': return 'Прокси-сервер'; + case 'NetCheckScreen.outboundOk': return ({required Object p}) => '[${p}]Соединение установлено успешно'; + case 'NetCheckScreen.outboundFailed': return ({required Object p1, required Object p2}) => '[${p1}]Соединение не удалось\nошибка:[${p2}]'; + case 'NetCheckScreen.dnsServer': return 'DNS сервер'; + case 'NetCheckScreen.dnsOk': return ({required Object p1, required Object p2, required Object p3, required Object p4}) => '[${p1}]DNS Разобрано успешно\nDNS правило:[${p2}]\nЗадержка:[${p3} ms]\nадрес:[${p4}]'; + case 'NetCheckScreen.dnsFailed': return ({required Object p1, required Object p2, required Object p3}) => '[${p1}]DNS Не удалось выполнить синтаксический анализ\n правило:[${p2}]\nошибка:[${p3}]'; + case 'NetCheckScreen.host': return 'HTTP соединение'; + case 'NetCheckScreen.hostConnection': return ({required Object p1, required Object p2, required Object p3}) => '[${p1}]\nПравила перенаправления:[${p2}]\nПрокси-сервер:[${p3}]'; + case 'NetCheckScreen.hostConnectionOk': return 'Соединение установлено успешно'; + case 'NetCheckScreen.hostConnectionFailed': return ({required Object p}) => 'Соединение не удалось:[${p}]'; + case 'NetConnectionsFilterScreen.title': return 'Фильтр соединений'; + case 'NetConnectionsFilterScreen.hostIp': return 'Domain/IP'; + case 'NetConnectionsFilterScreen.app': return 'Приложение'; + case 'NetConnectionsFilterScreen.rule': return 'Правило'; + case 'NetConnectionsFilterScreen.chain': return 'Исходящий'; + case 'NetConnectionsScreen.title': return 'Соединения'; + case 'NetConnectionsScreen.copyAsCSV': return 'Скопировано в CSV формате'; + case 'NetConnectionsScreen.selectType': return 'Выберите тип перенаправления'; + case 'PerAppAndroidScreen.title': return 'Проксируемые приложения'; + case 'PerAppAndroidScreen.whiteListMode': return 'Режим белого списка'; + case 'PerAppAndroidScreen.whiteListModeTip': return 'Если включено: перенаправляются через прокси-сервер только те приложения, которые были отмечены. Если выключено: перенаправляются через прокси-сервер только те приложения, которые не были отмечены.'; + case 'PerAppAndroidScreen.hideSystemApp': return 'Скрыть системные приложения'; + case 'PerAppAndroidScreen.hideAppIcon': return 'Скрыть значок приложения'; + case 'PerAppAndroidScreen.enableAppQueryPermission': return 'Включать разрешения [на запросы списка приложений]'; + case 'QrcodeScreen.tooLong': return 'Слишком большой текст для отображения'; + case 'QrcodeScreen.copy': return 'Скопировать ссылку'; + case 'QrcodeScreen.open': return 'Открыть ссылку'; + case 'QrcodeScreen.share': return 'Поделиться ссылкой'; + case 'QrcodeScreen.shareImage': return 'Поделиться QR-кодом'; + case 'RegionSettingsScreen.title': return 'Страна или регион'; + case 'RegionSettingsScreen.Regions': return 'Совет: Пожалуйста, правильно укажите текущую страну или регион. В противном случае это может вызвать проблемы с перенаправлением в сети'; + case 'ServerSelectScreen.title': return 'Выбор сервера'; + case 'ServerSelectScreen.autoSelectServer': return 'Автовыбор сервера с наименьшей задержкой'; + case 'ServerSelectScreen.recentUse': return 'Недавно использованные'; + case 'ServerSelectScreen.myFav': return 'Мои избранные'; + case 'ServerSelectScreen.selectLocal': return ({required Object p}) => 'Выбранный сервер является локальным, и может работать неправильно:${p}'; + case 'ServerSelectScreen.selectRequireEnableIPv6': return 'Выбранный сервер имеет адрес IPv6 и требует [Включить IPv6]'; + case 'ServerSelectScreen.selectDisabled': return 'Сервер отключен'; + case 'ServerSelectScreen.error404': return 'При измерении задержки произошла ошибка. Проверьте, существует ли профиль с таким содержимым.'; + case 'SettingsScreen.ispFaq': return ({required Object p}) => 'FAQ[${p}]'; + case 'SettingsScreen.cleanISP': return ({required Object p}) => 'Очистить ISP[${p}]'; + case 'SettingsScreen.openISP': return 'Открыть ссылку на провайдера'; + case 'SettingsScreen.cleanISPNoParam': return 'Очистить информацию об интернет-провайдере'; + case 'SettingsScreen.getTranffic': return 'Получить трафик'; + case 'SettingsScreen.tutorial': return 'Руководство'; + case 'SettingsScreen.commonlyUsedRulesets': return 'Коллекция наборов правил'; + case 'SettingsScreen.howToRemoveAds': return 'Как удалить рекламу'; + case 'SettingsScreen.htmlBoard': return 'Веб-панель'; + case 'SettingsScreen.dnsLeakDetection': return 'Тест утечки DNS'; + case 'SettingsScreen.speedTest': return 'Тест скорости'; + case 'SettingsScreen.downloadProfilePreferProxy': return 'Настройка приоритетного выбора прокси-сервера'; + case 'SettingsScreen.downloadProfilePreferProxyTips': return 'Если подключение установлено, профиль вначале будет загружен через подключенный прокси-сервер'; + case 'SettingsScreen.rulesetDirectDownlad': return 'Правила прямой загрузки'; + case 'SettingsScreen.hideUnusedDiversionGroup': return 'Скрыть неактивные правила перенаправления'; + case 'SettingsScreen.disableISPDiversionGroup': return 'Отключить правила перенаправления ISP'; + case 'SettingsScreen.portSetting': return 'Используемые порты'; + case 'SettingsScreen.portSettingRule': return 'Действуют все правила'; + case 'SettingsScreen.portSettingDirectAll': return 'Всё подключено напрямую'; + case 'SettingsScreen.portSettingProxyAll': return 'Всё идёт через прокси'; + case 'SettingsScreen.portSettingControl': return 'Управление и синхронизация'; + case 'SettingsScreen.portSettingCluster': return 'Кластерный сервис'; + case 'SettingsScreen.modifyPort': return 'Изменить порт'; + case 'SettingsScreen.modifyPortOccupied': return 'Порт занят, используйте другой порт'; + case 'SettingsScreen.ipStrategyTips': return 'Перед включением убедитесь, что ваша сеть поддерживает IPv6, в противном случае нормальный доступ к части трафика будет невозможен'; + case 'SettingsScreen.tunAppendHttpProxy': return 'Подключите HTTP-прокси к VPN'; + case 'SettingsScreen.tunAppendHttpProxyTips': return 'Некоторые приложения будут обходить устройство виртуальной сетевой карты и напрямую подключаться к HTTP-прокси.'; + case 'SettingsScreen.tlsInsecureEnable': return 'Пропустить проверку сертификата'; + case 'SettingsScreen.tlsFragmentEnable': return 'Включить фрагментацию TLS'; + case 'SettingsScreen.tlsFragmentSize': return 'Размер фрагмента TLS'; + case 'SettingsScreen.tlsFragmentSleep': return 'Длина фрагмента паузы TLS'; + case 'SettingsScreen.tlsMixedCaseSNIEnable': return 'Включить гибридный SNI TLS'; + case 'SettingsScreen.tlsPaddingEnable': return 'Включить заполнение TLS'; + case 'SettingsScreen.tlsPaddingSize': return 'Размер заполнения TLS'; + case 'SettingsScreen.dnsEnableRule': return 'Включить правила DNS'; + case 'SettingsScreen.dnsEnableFakeIp': return 'Включить FakeIP'; + case 'SettingsScreen.dnsEnableClientSubnet': return 'Включить ECS'; + case 'SettingsScreen.dnsEnableProxyResolveByProxy': return '[действующий поток] Разрешать DNS через прокси-сервер'; + case 'SettingsScreen.dnsEnableFinalResolveByProxy': return '[final] Разрешать DNS через прокси-сервер'; + case 'SettingsScreen.dnsTestDomain': return 'Тестовое доменное имя'; + case 'SettingsScreen.dnsTestDomainInvalid': return 'Неверное доменное имя'; + case 'SettingsScreen.dnsTypeOutbound': return 'Прокси-сервер'; + case 'SettingsScreen.dnsTypeDirect': return 'Прямой поток'; + case 'SettingsScreen.dnsTypeProxy': return 'Действующий поток'; + case 'SettingsScreen.dnsTypeResolver': return 'DNS-сервер'; + case 'SettingsScreen.dnsEnableRuleTips': return 'После включения, доменное имя выберет соответствующий DNS-сервер для разрешения в соответствии с правилами перенаправления.'; + case 'SettingsScreen.dnsEnableFakeIpTips': return 'После включения FakeIP, если VPN-соединение отключено, возможно, потребуется перезапустить приложение, эту функцию необходимо включить [Режим TUN];'; + case 'SettingsScreen.dnsTypeOutboundTips': return 'Для разрешения доменных имен прокси-сервера рекомендуется использовать безопасный DNS'; + case 'SettingsScreen.dnsTypeDirectTips': return 'Разрешение доменных имен для прямого потока'; + case 'SettingsScreen.dnsTypeProxyTips': return 'Разрешение доменных имен для действующего потока'; + case 'SettingsScreen.dnsTypeResolverTips': return 'Разрешение доменных имен для DNS-серверов'; + case 'SettingsScreen.dnsTypeFinalTips': return 'Разрешение доменных имен для потока Final'; + case 'SettingsScreen.dnsAutoSetServer': return 'Автоматически настроить сервер'; + case 'SettingsScreen.dnsResetServer': return 'Сбросить сервер'; + case 'SettingsScreen.inboundDomainResolve': return 'Разрешение входящих доменных имен'; + case 'SettingsScreen.privateDirect': return 'Прямое подключение к частной сети'; + case 'SettingsScreen.inboundDomainResolveTips': return ({required Object p}) => 'Некоторые доменные имена без настроенных правил переадресации необходимо разрешить, прежде чем они смогут соответствовать правилам переадресации на основе IP; эта функция влияет на входящие запросы к порту прокси [${p}]'; + case 'SettingsScreen.useRomoteRes': return 'Использовать удаленные ресурсы'; + case 'SettingsScreen.autoSelect': return 'Автовыбор'; + case 'SettingsScreen.autoSelectServerIgnorePerProxyServer': return 'Игнорировать прокси-сервер [передний прокси]'; + case 'SettingsScreen.autoSelectServerInterval': return 'Интервал проверок задержки'; + case 'SettingsScreen.autoSelectServerReTestIfNetworkUpdate': return 'Перетестировать после смены сети'; + case 'SettingsScreen.autoSelectServerIntervalTips': return 'Чем короче временной интервал, тем чаще обновляются данные о задержке сервера. Но это потребует больше ресурсов и энергии'; + case 'SettingsScreen.autoSelectServerFavFirst': return 'Приоритетно [Мои избранные]'; + case 'SettingsScreen.autoSelectServerUpdateCurrentServerAfterManualUrltest': return 'Обновить текущий сервер после измерения задержки вручную'; + case 'SettingsScreen.autoSelectServerFavFirstTips': return 'Если список [Мои избранные] не пуст, то будут использоваться серверы из [Мои избранные]'; + case 'SettingsScreen.autoSelectServerFilter': return 'Отфильтровать сервера'; + case 'SettingsScreen.autoSelectServerFilterTips': return ({required Object p}) => 'Ошибки превышения задержки сервера будут отфильтрованы; если после фильтрации ни один сервер не будет доступен, вместо него будут использоваться первые [${p}] серверы'; + case 'SettingsScreen.autoSelectServerLimitedNum': return 'Максимальное количество серверов'; + case 'SettingsScreen.autoSelectServerLimitedNumTips': return 'Серверы, превышающие это число, будут отфильтрованы.'; + case 'SettingsScreen.numInvalid': return 'Неправильный номер'; + case 'SettingsScreen.hideInvalidServer': return 'Скрыть нерабочие серверы'; + case 'SettingsScreen.sortServer': return 'Сортировка серверов'; + case 'SettingsScreen.sortServerTips': return 'Сортировать по задержке от низкой к высокой'; + case 'SettingsScreen.selectServerHideRecommand': return 'Скрыть [Рекомендуемые]'; + case 'SettingsScreen.selectServerHideRecent': return 'Скрыть [Недавно использованные]'; + case 'SettingsScreen.selectServerHideFav': return 'Скрыть [Мои избранные]'; + case 'SettingsScreen.homeScreen': return 'Настройка главного экрана'; + case 'SettingsScreen.theme': return 'Тема'; + case 'SettingsScreen.myLink': return 'Быстрая ссылка'; + case 'SettingsScreen.myLinkInvalid': return 'Неверный URL'; + case 'SettingsScreen.autoConnectAfterLaunch': return 'Автоматическое подключение после запуска'; + case 'SettingsScreen.hideAfterLaunch': return 'Скрыть окно после запуска'; + case 'SettingsScreen.autoSetSystemProxy': return 'Установить системный прокси после подключения'; + case 'SettingsScreen.disconnectWhenQuit': return 'Отключаться при выходе из приложения'; + case 'SettingsScreen.allowBypass': return 'Разрешить приложениям обходить VPN'; + case 'SettingsScreen.importSuccess': return 'Импорт выполнен успешно'; + case 'SettingsScreen.rewriteConfirm': return 'Этот файл перезапишет существующую локальную конфигурацию. Продолжить?'; + case 'SettingsScreen.networkShare': return 'Общий доступ к сети'; + case 'SettingsScreen.frontProxy': return 'Цепочка прокси'; + case 'SettingsScreen.frontProxyTips': return ({required Object p}) => 'Запрос -> Фронт-прокси ->[Цепочка прокси-серверов в порядке cверху вниз]-Выходной прокси [${p}] - Целевой сервер'; + case 'SettingsScreen.allowOtherHostsConnect': return 'Разрешить подключение по локальной сети'; + case 'SettingsScreen.allowOtherHostsConnectTips': return ({required Object sp, required Object hp}) => 'socks:${sp},http(s):${hp}'; + case 'SettingsScreen.tunAutoRoute': return 'Auto Route'; + case 'SettingsScreen.tunStrictRoute': return 'Strict Route'; + case 'SettingsScreen.tunStrictRouteTips': return 'Если после включения общего доступа другие люди не смогут получить доступ к этому устройству, попробуйте отключить этот переключатель.'; + case 'SettingsScreen.enableCluster': return 'Включить кластер прокси Socks/Http'; + case 'SettingsScreen.clusterAllowOtherHostsConnect': return 'Разрешить подключение по локальной сети к кластеру'; + case 'SettingsScreen.clusterAllowOtherHostsConnectTips': return ({required Object ip, required Object port}) => 'http://${ip}:${port}/get_proxies'; + case 'SettingsScreen.clusterAuth': return 'Аутентификация прокси-кластера'; + case 'SettingsScreen.tunMode': return 'Режим TUN'; + case 'SettingsScreen.tunModeTips': return 'В режиме TUN весь трафик системы будет перенаправлен через соединение [В этом режиме вы можете оставить системный прокси отключенным]'; + case 'SettingsScreen.tunModeRunAsAdmin': return 'Для режима TUN требуются права администратора. Перезапустите приложение от имени администратора'; + case 'SettingsScreen.tunStack': return 'Stack'; + case 'SettingsScreen.launchAtStartup': return 'Запуск при включении'; + case 'SettingsScreen.quitWhenSwitchSystemUser': return 'Выйти из приложения при переключении пользователя'; + case 'SettingsScreen.handleScheme': return 'Схемы системного вызова'; + case 'SettingsScreen.portableMode': return 'Портативный режим'; + case 'SettingsScreen.portableModeDisableTips': return 'Если вам нужно выйти из портативного режима, выйдите из [karing] и вручную удалите папку [profiles] в том же каталоге, что и [karing.exe]'; + case 'SettingsScreen.handleKaringScheme': return 'Вызов karing://[параметры]'; + case 'SettingsScreen.handleClashScheme': return 'Вызов clash://[параметры]'; + case 'SettingsScreen.handleSingboxScheme': return 'Вызов sing-box://[параметры]'; + case 'SettingsScreen.alwayOnVPN': return 'всегда открытое соединение'; + case 'SettingsScreen.removeSystemVPNConfig': return 'Удалить профиль VPN'; + case 'SettingsScreen.timeConnectOrDisconnect': return 'Запланированное подключение/отключение'; + case 'SettingsScreen.timeConnectOrDisconnectTips': return 'Чтобы это заработало, необходимо подключить VPN; после его подключения [автоматическое засыпание] будет отключено'; + case 'SettingsScreen.timeConnectAndDisconnectInterval': return ({required Object p}) => 'Интервал подключения/отключения не может быть меньше ${p} минут.'; + case 'SettingsScreen.disableFontScaler': return 'Отключить масштабирование шрифта'; + case 'SettingsScreen.autoOrientation': return 'Следовать за поворотом экрана'; + case 'SettingsScreen.restartTakesEffect': return 'Требуется перезапуск'; + case 'SettingsScreen.resetSettings': return 'Сброс настроек'; + case 'SettingsScreen.cleanCache': return 'Очистка кэша'; + case 'SettingsScreen.cleanCacheDone': return 'Очистка завершена'; + case 'SettingsScreen.appleTestFlight': return 'Apple TestFlight'; + case 'SettingsScreen.appleAppStore': return 'Apple AppStore'; + case 'SettingsScreen.hasNewVersion': return ({required Object p}) => 'Обновить версию ${p}'; + case 'SettingsScreen.follow': return 'Подписаться на нас'; + case 'SettingsScreen.contactUs': return 'Связаться с нами'; + case 'SettingsScreen.rateInApp': return 'Оценить нас'; + case 'SettingsScreen.rateInAppStore': return 'Оценить нас в App Store'; + case 'SpeedTestSettingsScreen.title': return 'URL-адрес теста скорости'; + case 'TextToQrCodeScreen.title': return 'Преобразование текста в QR-код'; + case 'TextToQrCodeScreen.convert': return 'Конвертировать'; + case 'UserAgreementScreen.privacyFirst': return 'Ваша конфиденциальность превыше всего'; + case 'UserAgreementScreen.agreeAndContinue': return 'Принять и продолжить'; + case 'VersionUpdateScreen.versionReady': return ({required Object p}) => 'Новая версия [${p}] доступна'; + case 'VersionUpdateScreen.update': return 'Перезапустить'; + case 'VersionUpdateScreen.cancel': return 'Не сейчас'; + case 'CommonWidget.diableAlwayOnVPN': return 'Если параметр [VPN всегда включен] включен, отключите его и попробуйте подключиться еще раз'; + case 'CommonWidget.resetPort': return 'Пожалуйста, измените порт на другой доступный порт или закройте приложение, занимающее порт.'; + case 'ServerManager.noServerAvaliable': return 'Нет доступных серверов, убедитесь что подписка или файл профиля корректен. Если ваша конфигурация взята из GitHub, получите адрес ссылки, нажав кнопку [Raw] на странице.'; + case 'ServerManager.filePathCannotEmpty': return 'Путь к файлу не может быть пустым'; + case 'ServerManager.fileNotExist': return ({required Object p}) => 'Файла не существует:${p}'; + case 'ServerManager.urlCannotEmpty': return 'Ссылка не может быть пустой'; + case 'ServerManager.invalidUrl': return 'Некорректная ссылка на подписку'; + case 'ServerManager.parseFailed': return 'Получение подписки не удалось'; + case 'main.tray.menuOpen': return ' Открыть '; + case 'main.tray.menuExit': return ' Выйти '; + case 'enable': return 'Включить'; + case 'disable': return 'Запретить'; + case 'filter': return 'Фильтр'; + case 'filterMethod': return 'Метод фильтра'; + case 'include': return 'Включать'; + case 'exclude': return 'Исключать'; + case 'all': return 'Все'; + case 'prefer': return 'Приоритет'; + case 'only': return 'Только'; + case 'open': return 'Открыть'; + case 'close': return 'Закрыть'; + case 'quit': return 'Выйти'; + case 'add': return 'Добавить'; + case 'remove': return 'Удалить'; + case 'edit': return 'Редактировать'; + case 'view': return 'Просмотр'; + case 'more': return 'Больше'; + case 'addProfile': return 'Добавить профиль'; + case 'addSuccess': return 'Добавлено успешно'; + case 'addSuccessThen': return ({required Object p}) => 'Конфигурация сгенерирована успешно. Для просмотра перейдите в [${p}]'; + case 'addFailed': return ({required Object p}) => 'Ошибка при добавлении:${p}'; + case 'removeConfirm': return 'Подтверждаете удаление?'; + case 'tips': return 'Инфо'; + case 'copy': return 'Скопировать'; + case 'ok': return 'Ок'; + case 'cancel': return 'Закрыть'; + case 'feedback': return 'Обратная связь'; + case 'faq': return 'Часто задаваемые вопросы (FAQ)'; + case 'download': return 'Скачать'; + case 'loading': return 'Загрузка...'; + case 'updateFailed': return ({required Object p}) => 'Не удалось обновить:${p}'; + case 'days': return 'дни'; + case 'hours': return 'часы'; + case 'minutes': return 'минуты'; + case 'seconds': return 'Второй'; + case 'protocol': return 'Протокол'; + case 'search': return 'Поиск'; + case 'custom': return 'Настроить самостоятельно'; + case 'connect': return 'Соединить'; + case 'disconnect': return 'Отключить'; + case 'connected': return 'Подключено'; + case 'disconnected': return 'Отключено'; + case 'connecting': return 'Подключение'; + case 'connectTimeout': return 'Таймаут при соединении'; + case 'timeout': return 'Тайм-аут'; + case 'language': return 'Язык'; + case 'next': return 'Дальше'; + case 'done': return 'Готово'; + case 'apply': return 'Применить'; + case 'refresh': return 'Обновить'; + case 'retry': return 'Хотите попробовать еще раз?'; + case 'none': return 'Ничего не делать'; + case 'reset': return 'Перезагрузить'; + case 'submit': return 'Отправить'; + case 'account': return 'Аккаунт'; + case 'password': return 'Пароль'; + case 'required': return 'Необходимо'; + case 'diversion': return 'Правила'; + case 'diversionRules': return 'Правила перенаправления'; + case 'diversionRulesEnable': return 'Включить правила перенаправления [ISP]'; + case 'diversionCustomGroup': return 'Личные правила'; + case 'diversionCustomGroupPreset': return 'Шаблоны личных правил'; + case 'diversionCustomGroupPresetTips': return 'Примечание. Включенные элементы будут добавлены в [Личные правила] и [Правила перенаправления].'; + case 'diversionCustomGroupAddTips': return 'Примечание. Возможно, вам придется вручную настроить порядок правил после их добавления, иначе добавленное перенаправление может работать не так, как ожидалось.'; + case 'urlTestCustomGroup': return 'Личная группа прокси-серверов'; + case 'rulesetEnableTips': return 'Совет: После включения опции перейдите в [Правила перенаправления] и установите их, иначе опция не будет действовать'; + case 'ispUserAgentTips': return '[ISP] будет доставлять различные типы данных о подписке на основе [UserAgent] в запросе [HTTP].'; + case 'ispDiversionTips': return 'Правила перенаправления, предоставляемые подписками [ISP] типа [V2Ray], не поддерживаются.'; + case 'staticIP': return 'Статический IP'; + case 'other': return 'Другой'; + case 'dns': return 'DNS'; + case 'url': return 'URL'; + case 'isp': return 'ISP'; + case 'tls': return 'TLS'; + case 'userAgent': return 'UserAgent'; + case 'urlInvalid': return 'Неверный URL'; + case 'outboundActionCurrentSelected': return 'Текущий сервер'; + case 'outboundActionUrltest': return 'Автовыбор сервера'; + case 'outboundActionDirect': return 'Напрямую'; + case 'outboundActionBlock': return 'Блокировать'; + case 'routeFinal': return 'Final'; + case 'rulesetGeoSite': return 'GeoSite'; + case 'rulesetGeoIp': return 'GeoIP'; + case 'rulesetAcl': return 'ACL'; + case 'iCloud': return 'iCloud'; + case 'appleTV': return 'Apple TV'; + case 'webdav': return 'Webdav'; + case 'setting': return 'Настройки'; + case 'protocolSniff': return 'Определение протокола'; + case 'protocolSniffOverrideDestination': return 'Обнаруженное имя домена перезаписывает целевой адрес подключения.'; + case 'remark': return 'Примечание'; + case 'remarkCannotEmpty': return 'Примечание не может быть пустым'; + case 'remarkTooLong': return 'Примечания до 32 символов'; + case 'remarkExist': return 'Примечание уже существует, используйте другое имя'; + case 'domainSuffix': return 'Суффикс доменного имени'; + case 'domain': return 'Имя домена'; + case 'domainKeyword': return 'Ключевые слова в имени домена'; + case 'domainRegex': return 'Регулярные выражения для имен доменов'; + case 'ip': return 'IP'; + case 'port': return 'Порт'; + case 'appPackage': return 'Имя пакета приложения'; + case 'processName': return 'Имя процесса'; + case 'processPath': return 'Путь к процессу'; + case 'systemProxy': return 'Системный прокси'; + case 'netInterfaces': return 'Сетевой интерфейс'; + case 'netSpeed': return 'Скорость'; + case 'website': return 'Веб-сайт'; + case 'rule': return 'Правила'; + case 'global': return 'Глобально'; + case 'qrcode': return 'QR-код'; + case 'scanQrcode': return 'Сканировать QR-код'; + case 'scanResult': return 'Результат сканирования'; + case 'backupAndSync': return 'Резервное копирование и синхронизация'; + case 'importAndExport': return 'Импорт и экспорт'; + case 'import': return 'Импорт'; + case 'export': return 'Экспорт'; + case 'send': return 'Передать'; + case 'receive': return 'Принять'; + case 'sendOrReceiveNotMatch': return ({required Object p}) => 'Пожалуйста, используйте [${p}]'; + case 'sendConfirm': return 'Подтверждаете передачу?'; + case 'termOfUse': return 'Условия использования'; + case 'privacyPolicy': return 'Политика конфиденциальности'; + case 'about': return 'О Karing'; + case 'name': return 'Название'; + case 'version': return 'Версия'; + case 'notice': return 'Уведомления'; + case 'sort': return 'Отсортировать'; + case 'novice': return 'Режим новичка'; + case 'recommended': return 'Рекомендуемые'; + case 'innerError': return ({required Object p}) => 'Внутренняя ошибка:${p}'; + case 'logicOperation': return 'Логическая опреация'; + case 'share': return 'Поделиться'; + case 'candidateWord': return 'Ключевые слова'; + case 'keywordOrRegx': return 'Ключевые слова/регулярные выражения'; + case 'importFromClipboard': return 'Импорт из буфера обмена'; + case 'exportToClipboard': return 'Экспорт в буфер обмена'; + case 'server': return 'Сервер'; + case 'appleTVConnectTurnOfprivateDirect': return 'Пожалуйста, сначала включите [Прямое подключение к частной сети]'; + case 'targetConnectFailed': return ({required Object p}) => 'Не удалось подключиться к [${p}]. Убедитесь, что устройство находится в той же локальной сети, и включите [Прямое подключение к частной сети].'; + case 'appleTVSync': return 'Синхронизация текущей базовой конфигурации с Apple TV - Karing'; + case 'appleTVSyncDone': return 'Синхронизация завершена, перейдите в Apple TV — Karing, чтобы открыть/перезапустить соединение.'; + case 'appleTVRemoveCoreConfig': return 'Удаление Apple TV — базовая конфигурация Karing'; + case 'appleTVRemoveCoreConfigDone': return 'Apple TV — основной профиль Karing удален; VPN-сервис отключен;'; + case 'appleTVUrlInvalid': return 'Неверный URL-адрес. Откройте Apple TV — Karing, отсканируйте QR-код, отображаемый Karing.'; + case 'remoteProfileEditConfirm': return 'После обновления конфигурации изменения узла будут восстановлены. Продолжить?'; + case 'invalidFileType': return ({required Object p}) => 'Неверный тип файла:${p}'; + case 'mustBeValidHttpsURL': return 'https URL должен быть действительным'; + case 'fileNotExistReinstall': return ({required Object p}) => 'Файл отсутствует [${p}], пожалуйста, переустановите'; + case 'latencyTest': return 'Обнаружение задержки'; + case 'latencyTestResolveIP': return 'При ручном определении также анализируется экспортный IP-адрес.'; + case 'uwpExemption': return 'Исключение из изоляции сети UWP'; + case 'removeBannerAds': return 'Удалить рекламу'; + case 'removeBannerAdsByReward': return 'Посмотрите несколько секунд рекламы, и вы будете вознаграждены 7 днями без рекламы.'; + case 'removeBannerAdsByRewardDone': return 'Получил награду в течение 7 дней без рекламы'; + case 'locales.en': return 'English'; + case 'locales.zh-CN': return '简体中文'; + case 'locales.ar': return 'عربي'; + case 'locales.ru': return 'Русский'; + case 'locales.fa': return 'فارسی'; + default: return null; + } + } +} + diff --git a/lib/i18n/strings_ru.i18n.json b/lib/i18n/strings_ru.i18n.json index 28e7bcb..6408bf5 100644 --- a/lib/i18n/strings_ru.i18n.json +++ b/lib/i18n/strings_ru.i18n.json @@ -1,9 +1,9 @@ { "AboutScreen": { - "installRefer": "Установленная ссылка", - "versionChannel": "Автоматически обновлять канал", + "installRefer": "Ссылка на установку", + "versionChannel": "Канал автоматического обновления", "disableUAReport": "Отключить аналитику", - "disableUAReportTip": "Отчеты о поведенческих данных помогают нам улучшить работу с продуктом; версии ниже основной версии автоматически отключают все отчеты о данных (кроме [Активации приложения]).", + "disableUAReportTip": "Данные отчётов о поведении программы помогают нам улучшить её работу; версии младше основной автоматически отключают все отчеты (кроме [Запуска приложения]).", "devOptions": "Параметры разработчика", "enableDebugLog": "Включить debug-лог", "viewFilsContent": "Посмотреть файлы", @@ -20,7 +20,7 @@ "AddProfileByLinkOrContentScreen": { "title": "Добавление подписки", "updateTimerInterval": "Интервал обновления", - "updateTimerIntervalTips": "Чтобы отключить, установите:< 5 мин", + "updateTimerIntervalTips": "Минимум: 5 м", "profileLinkContent": "Ссылка на подписку/содержание", "profileLinkContentHit": "Ссылка на подписку/содержание [обязательно] (Поддерживаются Clash, V2ray(c пакетом поддержки), Stash, Karing, Sing-box, Shadowsocks, Sub; Ссылка на конфигурацию).", "subscriptionCannotEmpty": "Ссылка на подписку не может быть пустой", @@ -57,7 +57,7 @@ "invalidPort": "Неверный [Port]:$p", "invalidRuleSet": "Неверный [Rule Set]:$p, URL-адрес должен быть действительным URL-адресом https двоичного файлом с расширением .srs/.json", "invalidRuleSetBuildIn": "Неверный [RuleSet(build-in)]:$p, формат: geosite:xxx или geoip:xxx или acl:xxx, а xxx должно быть допустимым именем правила.", - "setDiversionRule": "Совет: после сохранения перейдите в раздел [Правила перенаправления] и установите их, иначе изменения не будут действовать." + "setDiversionRule": "Совет: после сохранения перейдите в раздел [Правила перенаправления] и настройте их, иначе изменения не будут действовать." }, "DiversionRuleDetectScreen": { "title": "Тест правил перенаправления", @@ -72,7 +72,7 @@ "ispCanNotEmpty": "ISP не может быть пустой", "urlCanNotEmpty": "URL не может быть пустой", "error": "Неподдерживаемый тип:$p", - "dnsDesc": "Первый столбец данных — это задержка запроса при прямом соединении;\nВторой столбец, если включено [[действующий поток]Разрешать DNS через прокси-сервер]: данные — это задержка запроса, пересылаемого через текущий прокси-сервер; Если выключено [[действующий поток] Разрешать DNS через прокси-сервер]: данные - это задержка запроса при прямом соединении." + "dnsDesc": "Первый столбец данных — это задержка запроса при прямом соединении;\nВторой столбец, если включено [[действующий поток] Разрешать DNS через прокси-сервер]: данные — это задержка запроса, пересылаемого через текущий прокси-сервер; Если выключено [[действующий поток] Разрешать DNS через прокси-сервер]: данные - это задержка запроса при прямом соединении." }, "FeedbackScreen": { "content": "Содержание", @@ -87,7 +87,7 @@ }, "HomeScreen": { "toSelectServer": "Выберите сервер", - "invalidServer": "Просрочен. Пожалуйста, выберите другой", + "invalidServer": "Не работает. Пожалуйста, выберите другой", "disabledServer": "Был отключен. Пожалуйста, выберите другой", "expiredServer": "Нет доступного сервера: возможно, профиль устарел или отключен", "systemProxyTips": "socks:$sp,http(s):$hp", @@ -102,13 +102,13 @@ "invalidProfile": "Не удалось запустить приложение [Не удалось получить доступ к профилю], переустановите приложение", "invalidVersion": "Не удалось запустить приложение [Неверная версия], переустановите приложение", "systemVersionLow": "Не удалось запустить приложение [Слишком низкая версия системы]", - "startFromUNC": "Путь установки недействителен, переустановите его по допустимому пути" + "invalidInstallPath": "Путь установки недействителен, переустановите его по допустимому пути" }, "MyProfilesEditScreen": { "title": "Редактирование профилей", "urlExist": "URL-адрес уже существует, используйте другой URL-адрес", "updateTimerInterval": "Интервал обновления", - "updateTimerIntervalTips": "Чтобы отключить, установите <5 мин", + "updateTimerIntervalTips": "Минимум: 5 м", "reloadAfterProfileUpdate": "Перезагрузить после обновления профиля", "testLatencyAfterProfileUpdate": "Начать тестирование задержек после обновления профиля", "testLatencyAfterProfileUpdateTips": "VPN необходимо подключить, и включить [Перезагрузить после обновления профиля]", @@ -138,7 +138,7 @@ "connectivityTestOk": "Сеть подключена к Интернету", "connectivityTestFailed": "Ваша сеть не подключена к Интернету", "remoteRulesetsDownloadOk": "Все успешно скачано", - "remoteRulesetsDownloadNotOk": "Загрузка или сбой", + "remoteRulesetsDownloadNotOk": "Сбой загрузки", "outbound": "Прокси-сервер", "outboundOk": "[$p]Соединение установлено успешно", "outboundFailed": "[$p1]Соединение не удалось\nошибка:[$p2]", @@ -198,30 +198,31 @@ "cleanISPNoParam": "Очистить информацию об интернет-провайдере", "getTranffic": "Получить трафик", "tutorial": "Руководство", - "commonlyUsedRulesets": "Часто используемые наборы правил", + "commonlyUsedRulesets": "Коллекция наборов правил", "howToRemoveAds": "Как удалить рекламу", "htmlBoard": "Веб-панель", - "dnsLeakDetection": "Обнаружение утечки DNS", + "dnsLeakDetection": "Тест утечки DNS", "speedTest": "Тест скорости", "downloadProfilePreferProxy": "Настройка приоритетного выбора прокси-сервера", "downloadProfilePreferProxyTips": "Если подключение установлено, профиль вначале будет загружен через подключенный прокси-сервер", - "rulesetDirectDownlad": "Rule Set Прямой доступ", + "rulesetDirectDownlad": "Правила прямой загрузки", "hideUnusedDiversionGroup": "Скрыть неактивные правила перенаправления", "disableISPDiversionGroup": "Отключить правила перенаправления ISP", - "portSetting": "Порт", - "portSettingRule": "Основано на правилах", - "portSettingDirectAll": "Полное прямое соединение", - "portSettingProxyAll": "Прокси для всего", + "portSetting": "Используемые порты", + "portSettingRule": "Действуют все правила", + "portSettingDirectAll": "Всё подключено напрямую", + "portSettingProxyAll": "Всё идёт через прокси", "portSettingControl": "Управление и синхронизация", "portSettingCluster": "Кластерный сервис", "modifyPort": "Изменить порт", + "modifyPortOccupied": "Порт занят, используйте другой порт", "ipStrategyTips": "Перед включением убедитесь, что ваша сеть поддерживает IPv6, в противном случае нормальный доступ к части трафика будет невозможен", "tunAppendHttpProxy": "Подключите HTTP-прокси к VPN", "tunAppendHttpProxyTips": "Некоторые приложения будут обходить устройство виртуальной сетевой карты и напрямую подключаться к HTTP-прокси.", "tlsInsecureEnable": "Пропустить проверку сертификата", - "tlsFragmentEnable": "Включить сегментацию TLS", - "tlsFragmentSize": "Размер сегмента TLS", - "tlsFragmentSleep": "Сегментированный сон TLS", + "tlsFragmentEnable": "Включить фрагментацию TLS", + "tlsFragmentSize": "Размер фрагмента TLS", + "tlsFragmentSleep": "Длина фрагмента паузы TLS", "tlsMixedCaseSNIEnable": "Включить гибридный SNI TLS", "tlsPaddingEnable": "Включить заполнение TLS", "tlsPaddingSize": "Размер заполнения TLS", @@ -268,53 +269,48 @@ "selectServerHideRecommand": "Скрыть [Рекомендуемые]", "selectServerHideRecent": "Скрыть [Недавно использованные]", "selectServerHideFav": "Скрыть [Мои избранные]", - "homeScreen": "Домашний экран", + "homeScreen": "Настройка главного экрана", "theme": "Тема", "myLink": "Быстрая ссылка", "myLinkInvalid": "Неверный URL", "autoConnectAfterLaunch": "Автоматическое подключение после запуска", "hideAfterLaunch": "Скрыть окно после запуска", - "autoSetSystemProxy": "Установить прокси после подключения", + "autoSetSystemProxy": "Установить системный прокси после подключения", "disconnectWhenQuit": "Отключаться при выходе из приложения", "allowBypass": "Разрешить приложениям обходить VPN", - "lanSyncTo": "Синхронизировать на другие устройства", - "lanSyncFrom": "Синхронизация с других устройств", - "lanSyncScanQRcode": "Сканируйте QR-код для синхронизации", - "syncToConfirm": "Подтвердить синхронизацию с собеседником?", - "syncDone": "Синхронизация завершена", "importSuccess": "Импорт выполнен успешно", "rewriteConfirm": "Этот файл перезапишет существующую локальную конфигурацию. Продолжить?", "networkShare": "Общий доступ к сети", - "frontProxy": "Фронт-прокси", - "frontProxyTips": "Запрос -> фронт-прокси сервер -> прокси-сервер -> целевой сервер", - "allowOtherHostsConnect": "Разрешить подключаться другим", + "frontProxy": "Цепочка прокси", + "frontProxyTips": "Запрос -> Фронт-прокси ->[Цепочка прокси-серверов в порядке cверху вниз]-Выходной прокси [$p] - Целевой сервер", + "allowOtherHostsConnect": "Разрешить подключение по локальной сети", "allowOtherHostsConnectTips": "socks:$sp,http(s):$hp", "tunAutoRoute": "Auto Route", "tunStrictRoute": "Strict Route", "tunStrictRouteTips": "Если после включения общего доступа другие люди не смогут получить доступ к этому устройству, попробуйте отключить этот переключатель.", "enableCluster": "Включить кластер прокси Socks/Http", - "clusterAllowOtherHostsConnect": "Разрешить подключаться другим", - "clusterAllowOtherHostsConnectTips": "http://127.0.0.1:$hp/get_proxies", + "clusterAllowOtherHostsConnect": "Разрешить подключение по локальной сети к кластеру", + "clusterAllowOtherHostsConnectTips": "http://$ip:$port/get_proxies", "clusterAuth": "Аутентификация прокси-кластера", - "clusterConfirm": "Пожалуйста, подтвердите, что задержка серверов проверена. Прокси-сервисы не будут созданы, если они не проверены или проверены неверно", "tunMode": "Режим TUN", "tunModeTips": "В режиме TUN весь трафик системы будет перенаправлен через соединение [В этом режиме вы можете оставить системный прокси отключенным]", "tunModeRunAsAdmin": "Для режима TUN требуются права администратора. Перезапустите приложение от имени администратора", "tunStack": "Stack", "launchAtStartup": "Запуск при включении", - "quitWhenSwitchSystemUser": "Переключить пользователя для выхода", - "handleScheme": "Использовать схему системы с предварительным звонком", + "quitWhenSwitchSystemUser": "Выйти из приложения при переключении пользователя", + "handleScheme": "Схемы системного вызова", "portableMode": "Портативный режим", "portableModeDisableTips": "Если вам нужно выйти из портативного режима, выйдите из [karing] и вручную удалите папку [profiles] в том же каталоге, что и [karing.exe]", - "handleKaringScheme": "Кнопка karing:// Позвонить", - "handleClashScheme": "Кнопка clash:// Позвонить", - "handleSingboxScheme": "Кнопка sing-box:// Позвонить", + "handleKaringScheme": "Вызов karing://[параметры]", + "handleClashScheme": "Вызов clash://[параметры]", + "handleSingboxScheme": "Вызов sing-box://[параметры]", + "alwayOnVPN": "всегда открытое соединение", "removeSystemVPNConfig": "Удалить профиль VPN", "timeConnectOrDisconnect": "Запланированное подключение/отключение", "timeConnectOrDisconnectTips": "Чтобы это заработало, необходимо подключить VPN; после его подключения [автоматическое засыпание] будет отключено", "timeConnectAndDisconnectInterval": "Интервал подключения/отключения не может быть меньше $p минут.", "disableFontScaler": "Отключить масштабирование шрифта", - "autoOrientation": "Следите за поворотом экрана", + "autoOrientation": "Следовать за поворотом экрана", "restartTakesEffect": "Требуется перезапуск", "resetSettings": "Сброс настроек", "cleanCache": "Очистка кэша", @@ -328,17 +324,12 @@ "rateInAppStore": "Оценить нас в App Store" }, "SpeedTestSettingsScreen": { - "title": "URL-адрес теста скорости", - "error": "https URL должен быть действительным" + "title": "URL-адрес теста скорости" }, "TextToQrCodeScreen": { "title": "Преобразование текста в QR-код", "convert": "Конвертировать" }, - "UrlTestSettingsScreen": { - "title": "URL-адрес измерения задержки", - "error": "https URL должен быть действительным" - }, "UserAgreementScreen": { "privacyFirst": "Ваша конфиденциальность превыше всего", "agreeAndContinue": "Принять и продолжить" @@ -368,6 +359,11 @@ }, "enable": "Включить", "disable": "Запретить", + "filter": "Фильтр", + "filterMethod": "Метод фильтра", + "include": "Включать", + "exclude": "Исключать", + "all": "Все", "prefer": "Приоритет", "only": "Только", "open": "Открыть", @@ -376,8 +372,8 @@ "add": "Добавить", "remove": "Удалить", "edit": "Редактировать", - "view": "Более", - "more": "More", + "view": "Просмотр", + "more": "Больше", "addProfile": "Добавить профиль", "addSuccess": "Добавлено успешно", "addSuccessThen": "Конфигурация сгенерирована успешно. Для просмотра перейдите в [$p]", @@ -405,7 +401,7 @@ "disconnected": "Отключено", "connecting": "Подключение", "connectTimeout": "Таймаут при соединении", - "timeout": "тайм-аут", + "timeout": "Тайм-аут", "language": "Язык", "next": "Дальше", "done": "Готово", @@ -420,15 +416,15 @@ "required": "Необходимо", "diversion": "Правила", "diversionRules": "Правила перенаправления", - "diversionRulesEnable": "Включить правила разгрузки [ISP]", + "diversionRulesEnable": "Включить правила перенаправления [ISP]", "diversionCustomGroup": "Личные правила", "diversionCustomGroupPreset": "Шаблоны личных правил", - "diversionCustomGroupPresetTips": "Примечание. Включенные элементы будут добавлены или включены в [Личные правила] и [Правила перенаправления].", - "diversionCustomGroupAddTips": "Примечание. Возможно, вам придется вручную настроить сортировку после ее добавления, в противном случае добавленное перенаправление может не вступить в силу.", + "diversionCustomGroupPresetTips": "Примечание. Включенные элементы будут добавлены в [Личные правила] и [Правила перенаправления].", + "diversionCustomGroupAddTips": "Примечание. Возможно, вам придется вручную настроить порядок правил после их добавления, иначе добавленное перенаправление может работать не так, как ожидалось.", "urlTestCustomGroup": "Личная группа прокси-серверов", "rulesetEnableTips": "Совет: После включения опции перейдите в [Правила перенаправления] и установите их, иначе опция не будет действовать", "ispUserAgentTips": "[ISP] будет доставлять различные типы данных о подписке на основе [UserAgent] в запросе [HTTP].", - "ispDiversionTips": "Правила разгрузки, предоставляемые подписками типа [ISP] [V2Ray], не поддерживают правила разгрузки;", + "ispDiversionTips": "Правила перенаправления, предоставляемые подписками [ISP] типа [V2Ray], не поддерживаются.", "staticIP":"Статический IP", "other": "Другой", "dns": "DNS", @@ -449,8 +445,8 @@ "appleTV": "Apple TV", "webdav": "Webdav", "setting": "Настройки", - "protocolSniff": "Обнаружение протокола", - "protocolSniffOverrideDestination": "Обнаруженное доменное имя охватывает целевой адрес подключения.", + "protocolSniff": "Определение протокола", + "protocolSniffOverrideDestination": "Обнаруженное имя домена перезаписывает целевой адрес подключения.", "remark": "Примечание", "remarkCannotEmpty": "Примечание не может быть пустым", "remarkTooLong": "Примечания до 32 символов", @@ -477,6 +473,10 @@ "importAndExport": "Импорт и экспорт", "import": "Импорт", "export": "Экспорт", + "send": "Передать", + "receive": "Принять", + "sendOrReceiveNotMatch": "Пожалуйста, используйте [$p]", + "sendConfirm": "Подтверждаете передачу?", "termOfUse": "Условия использования", "privacyPolicy": "Политика конфиденциальности", "about": "О Karing", @@ -486,14 +486,14 @@ "sort": "Отсортировать", "novice": "Режим новичка", "recommended": "Рекомендуемые", - "innerError": "внутренняя ошибка:$p", - "logicOperation": "логическая операция", + "innerError": "Внутренняя ошибка:$p", + "logicOperation": "Логическая опреация", "share": "Поделиться", "candidateWord": "Ключевые слова", - "keywordsOrRegx": "Ключевые слова/регулярные выражения", + "keywordOrRegx": "Ключевые слова/регулярные выражения", "importFromClipboard": "Импорт из буфера обмена", "exportToClipboard": "Экспорт в буфер обмена", - "server": "сервер", + "server": "Сервер", "appleTVConnectTurnOfprivateDirect": "Пожалуйста, сначала включите [Прямое подключение к частной сети]", "targetConnectFailed": "Не удалось подключиться к [$p]. Убедитесь, что устройство находится в той же локальной сети, и включите [Прямое подключение к частной сети].", "appleTVSync":"Синхронизация текущей базовой конфигурации с Apple TV - Karing", @@ -503,6 +503,14 @@ "appleTVUrlInvalid": "Неверный URL-адрес. Откройте Apple TV — Karing, отсканируйте QR-код, отображаемый Karing.", "remoteProfileEditConfirm": "После обновления конфигурации изменения узла будут восстановлены. Продолжить?", "invalidFileType": "Неверный тип файла:$p", + "mustBeValidHttpsURL": "https URL должен быть действительным", + "fileNotExistReinstall": "Файл отсутствует [$p], пожалуйста, переустановите", + "latencyTest": "Обнаружение задержки", + "latencyTestResolveIP": "При ручном определении также анализируется экспортный IP-адрес.", + "uwpExemption": "Исключение из изоляции сети UWP", + "removeBannerAds": "Удалить рекламу", + "removeBannerAdsByReward": "Посмотрите несколько секунд рекламы, и вы будете вознаграждены 7 днями без рекламы.", + "removeBannerAdsByRewardDone": "Получил награду в течение 7 дней без рекламы", "locales(map)": { "en": "English", "zh-CN": "简体中文", diff --git a/lib/i18n/strings_zh-CN.i18n.json b/lib/i18n/strings_zh-CN.i18n.json index cbd80bc..252906c 100644 --- a/lib/i18n/strings_zh-CN.i18n.json +++ b/lib/i18n/strings_zh-CN.i18n.json @@ -20,7 +20,7 @@ "AddProfileByLinkOrContentScreen": { "title": "添加配置链接", "updateTimerInterval": "更新时间间隔", - "updateTimerIntervalTips": "禁用请设置为:<5m", + "updateTimerIntervalTips": "最小:5m", "profileLinkContent": "配置链接/内容", "profileLinkContentHit": "配置链接/内容[必填] (支持Clash,V2ray(支持批量),Stash,Karing,Sing-box,Shadowsocks,Sub,Github配置链接)", "subscriptionCannotEmpty": "配置链接不能为空", @@ -102,13 +102,13 @@ "invalidProfile": "应用启动失败[访问配置文件失败],请重新安装应用", "invalidVersion": "应用启动失败[无效版本],请重新安装应用", "systemVersionLow": "应用启动失败[系统版本过低]", - "startFromUNC": "无效的安装路径,请重新安装到有效路径" + "invalidInstallPath": "无效的安装路径,请重新安装到有效路径" }, "MyProfilesEditScreen": { "title": "编辑配置", "urlExist": "URL已存在,请使用其他URL", "updateTimerInterval": "更新时间间隔", - "updateTimerIntervalTips": "禁用请设置为:<5m", + "updateTimerIntervalTips": "最小:5m", "reloadAfterProfileUpdate": "配置更新后重新加载", "testLatencyAfterProfileUpdate": "配置自动更新后启动延迟测试", "testLatencyAfterProfileUpdateTips": "VPN需要处于已连接状态,并且开启[配置更新后重新加载]", @@ -215,6 +215,7 @@ "portSettingControl": "控制与同步", "portSettingCluster": "集群服务", "modifyPort": "修改端口", + "modifyPortOccupied": "端口已被占用,请使用其他端口", "ipStrategyTips": "启用前,请先确认你的网络已支持IPv6,否则某些流量无法正常访问", "tunAppendHttpProxy": "附加HTTP代理到VPN", "tunAppendHttpProxyTips": "一些App会绕过虚拟网卡设备直连HTTP代理", @@ -277,16 +278,11 @@ "autoSetSystemProxy": "连接后自动设置系统代理", "disconnectWhenQuit": "退出应用时关闭连接", "allowBypass": "允许应用绕过VPN", - "lanSyncTo": "同步给他人", - "lanSyncFrom": "从他人同步", - "lanSyncScanQRcode": "扫码同步", - "syncToConfirm": "确认同步给对方?", - "syncDone": "同步完成", "importSuccess": "导入成功", "rewriteConfirm": "该文件将覆盖本地已有配置,是否继续?", "networkShare": "网络共享", "frontProxy": "前置代理", - "frontProxyTips": "数据->前置代理服务器->代理服务器->目标服务器", + "frontProxyTips": "数据->前置代理服务器[多个前置代理服务器:由上到下]->代理服务器[$p]->目标服务器", "allowOtherHostsConnect": "允许其他主机接入", "allowOtherHostsConnectTips": "socks:$sp,http(s):$hp", "tunAutoRoute": "Auto Route", @@ -294,9 +290,8 @@ "tunStrictRouteTips": "如果开启共享后,其他无法接入此设备,请尝试关闭此开关", "enableCluster": "开启Socks/Http代理集群", "clusterAllowOtherHostsConnect": "允许其他主机接入代理集群", - "clusterAllowOtherHostsConnectTips": "http://127.0.0.1:$hp/get_proxies", + "clusterAllowOtherHostsConnectTips": "http://$ip:$port/get_proxies", "clusterAuth": "代理集群认证", - "clusterConfirm": "请确认服务器已经过服务器延迟检测,未检测或者检测出错的将不会创建代理服务", "tunMode": "TUN模式", "tunModeTips": "TUN模式将接管系统所有流量[此模式下无需开启系统代理]", "tunModeRunAsAdmin": "TUN模式需要系统管理员权限,请以管理员身份重新启动应用", @@ -309,6 +304,7 @@ "handleKaringScheme": "处理karing://调用", "handleClashScheme": "处理clash://调用", "handleSingboxScheme": "处理sing-box://调用", + "alwayOnVPN": "始终开启连接", "removeSystemVPNConfig": "删除系统VPN配置", "timeConnectOrDisconnect": "定时连接/断开", "timeConnectOrDisconnectTips": "VPN必须处于连接状态才会生效;开启后,[自动休眠]将失效", @@ -328,17 +324,12 @@ "rateInAppStore": "在App Store上评分" }, "SpeedTestSettingsScreen": { - "title": "测速URL", - "error": "必须为有效的 https URL" + "title": "测速URL" }, "TextToQrCodeScreen": { "title": "文本转二维码", "convert": "转换" }, - "UrlTestSettingsScreen": { - "title": "延迟检测URL", - "error": "必须为有效的 https URL" - }, "UserAgreementScreen": { "privacyFirst": "您的隐私很重要", "agreeAndContinue": "接受并继续" @@ -368,6 +359,11 @@ }, "enable": "启用", "disable": "禁用", + "filter": "过滤", + "filterMethod": "过滤方式", + "include": "包含", + "exclude": "排除", + "all": "所有", "prefer": "优先", "only": "仅", "open": "打开", @@ -477,6 +473,10 @@ "importAndExport": "导入/导出", "import": "导入", "export": "导出", + "send": "发送", + "receive": "接收", + "sendOrReceiveNotMatch": "请使用[$p]", + "sendConfirm": "确认发送?", "termOfUse": "使用条款", "privacyPolicy": "隐私政策", "about": "关于", @@ -490,9 +490,9 @@ "logicOperation": "逻辑运算", "share": "分享", "candidateWord": "候选词", - "keywordsOrRegx": "关键词/正则", - "importFromClipboard": "从剪切板导入", - "exportToClipboard": "导出到剪切板", + "keywordOrRegx": "关键词/正则", + "importFromClipboard": "从剪贴板导入", + "exportToClipboard": "导出到剪贴板", "server": "服务器", "appleTVConnectTurnOfprivateDirect": "请先开启[私有网络直连]", "targetConnectFailed": "连接[$p]失败,请确保设备在同一个局域网内,并且开启[私有网络直连]", @@ -503,6 +503,14 @@ "appleTVUrlInvalid": "无效的URL,请打开Apple TV - Karing,扫描Karing显示的二维码", "remoteProfileEditConfirm": "配置更新后,节点的修改将会被还原,是否继续?", "invalidFileType": "无效的文件类型:$p", + "mustBeValidHttpsURL": "必须为有效的 https URL", + "fileNotExistReinstall": "文件缺失[$p],请重新安装", + "latencyTest": "延迟检测", + "latencyTestResolveIP": "手动检测时,同时解析出口IP", + "uwpExemption": "UWP网络隔离豁免", + "removeBannerAds": "去除广告", + "removeBannerAdsByReward": "观看一段数秒广告,将会获得7天无广告奖励", + "removeBannerAdsByRewardDone": "已获得7天无广告奖励", "locales(map)": { "en": "English", "zh-CN": "简体中文", diff --git a/lib/i18n/strings_zh_CN.g.dart b/lib/i18n/strings_zh_CN.g.dart new file mode 100644 index 0000000..95ba01f --- /dev/null +++ b/lib/i18n/strings_zh_CN.g.dart @@ -0,0 +1,1281 @@ +/// +/// Generated file. Do not edit. +/// +// coverage:ignore-file +// ignore_for_file: type=lint, unused_import + +import 'package:flutter/widgets.dart'; +import 'package:intl/intl.dart'; +import 'package:slang/generated.dart'; +import 'strings.g.dart'; + +// Path: +class TranslationsZhCn implements Translations { + /// You can call this constructor and build your own translation instance of this locale. + /// Constructing via the enum [AppLocale.build] is preferred. + TranslationsZhCn({Map? overrides, PluralResolver? cardinalResolver, PluralResolver? ordinalResolver}) + : assert(overrides == null, 'Set "translation_overrides: true" in order to enable this feature.'), + $meta = TranslationMetadata( + locale: AppLocale.zhCn, + overrides: overrides ?? {}, + cardinalResolver: cardinalResolver, + ordinalResolver: ordinalResolver, + ) { + $meta.setFlatMapFunction(_flatMapFunction); + } + + /// Metadata for the translations of . + @override final TranslationMetadata $meta; + + /// Access flat map + @override dynamic operator[](String key) => $meta.getTranslation(key); + + late final TranslationsZhCn _root = this; // ignore: unused_field + + // Translations + @override late final _TranslationsAboutScreenZhCn AboutScreen = _TranslationsAboutScreenZhCn._(_root); + @override late final _TranslationsAddProfileByImportFromFileScreenZhCn AddProfileByImportFromFileScreen = _TranslationsAddProfileByImportFromFileScreenZhCn._(_root); + @override late final _TranslationsAddProfileByLinkOrContentScreenZhCn AddProfileByLinkOrContentScreen = _TranslationsAddProfileByLinkOrContentScreenZhCn._(_root); + @override late final _TranslationsAddProfileByScanQrcodeScanScreenZhCn AddProfileByScanQrcodeScanScreen = _TranslationsAddProfileByScanQrcodeScanScreenZhCn._(_root); + @override late final _TranslationsBackupAndSyncLanSyncScreenZhCn BackupAndSyncLanSyncScreen = _TranslationsBackupAndSyncLanSyncScreenZhCn._(_root); + @override late final _TranslationsBackupAndSyncWebdavScreenZhCn BackupAndSyncWebdavScreen = _TranslationsBackupAndSyncWebdavScreenZhCn._(_root); + @override late final _TranslationsDiversionGroupCustomEditScreenZhCn DiversionGroupCustomEditScreen = _TranslationsDiversionGroupCustomEditScreenZhCn._(_root); + @override late final _TranslationsDiversionRuleDetectScreenZhCn DiversionRuleDetectScreen = _TranslationsDiversionRuleDetectScreenZhCn._(_root); + @override late final _TranslationsDiversionRulesScreenZhCn DiversionRulesScreen = _TranslationsDiversionRulesScreenZhCn._(_root); + @override late final _TranslationsDnsSettingsScreenZhCn DnsSettingsScreen = _TranslationsDnsSettingsScreenZhCn._(_root); + @override late final _TranslationsFeedbackScreenZhCn FeedbackScreen = _TranslationsFeedbackScreenZhCn._(_root); + @override late final _TranslationsFileContentViewerScreenZhCn FileContentViewerScreen = _TranslationsFileContentViewerScreenZhCn._(_root); + @override late final _TranslationsHomeScreenZhCn HomeScreen = _TranslationsHomeScreenZhCn._(_root); + @override late final _TranslationsLaunchFailedScreenZhCn LaunchFailedScreen = _TranslationsLaunchFailedScreenZhCn._(_root); + @override late final _TranslationsMyProfilesEditScreenZhCn MyProfilesEditScreen = _TranslationsMyProfilesEditScreenZhCn._(_root); + @override late final _TranslationsMyProfilesMergeScreenZhCn MyProfilesMergeScreen = _TranslationsMyProfilesMergeScreenZhCn._(_root); + @override late final _TranslationsMyProfilesScreenZhCn MyProfilesScreen = _TranslationsMyProfilesScreenZhCn._(_root); + @override late final _TranslationsNetCheckScreenZhCn NetCheckScreen = _TranslationsNetCheckScreenZhCn._(_root); + @override late final _TranslationsNetConnectionsFilterScreenZhCn NetConnectionsFilterScreen = _TranslationsNetConnectionsFilterScreenZhCn._(_root); + @override late final _TranslationsNetConnectionsScreenZhCn NetConnectionsScreen = _TranslationsNetConnectionsScreenZhCn._(_root); + @override late final _TranslationsPerAppAndroidScreenZhCn PerAppAndroidScreen = _TranslationsPerAppAndroidScreenZhCn._(_root); + @override late final _TranslationsQrcodeScreenZhCn QrcodeScreen = _TranslationsQrcodeScreenZhCn._(_root); + @override late final _TranslationsRegionSettingsScreenZhCn RegionSettingsScreen = _TranslationsRegionSettingsScreenZhCn._(_root); + @override late final _TranslationsServerSelectScreenZhCn ServerSelectScreen = _TranslationsServerSelectScreenZhCn._(_root); + @override late final _TranslationsSettingsScreenZhCn SettingsScreen = _TranslationsSettingsScreenZhCn._(_root); + @override late final _TranslationsSpeedTestSettingsScreenZhCn SpeedTestSettingsScreen = _TranslationsSpeedTestSettingsScreenZhCn._(_root); + @override late final _TranslationsTextToQrCodeScreenZhCn TextToQrCodeScreen = _TranslationsTextToQrCodeScreenZhCn._(_root); + @override late final _TranslationsUserAgreementScreenZhCn UserAgreementScreen = _TranslationsUserAgreementScreenZhCn._(_root); + @override late final _TranslationsVersionUpdateScreenZhCn VersionUpdateScreen = _TranslationsVersionUpdateScreenZhCn._(_root); + @override late final _TranslationsCommonWidgetZhCn CommonWidget = _TranslationsCommonWidgetZhCn._(_root); + @override late final _TranslationsServerManagerZhCn ServerManager = _TranslationsServerManagerZhCn._(_root); + @override late final _TranslationsMainZhCn main = _TranslationsMainZhCn._(_root); + @override String get enable => '启用'; + @override String get disable => '禁用'; + @override String get filter => '过滤'; + @override String get filterMethod => '过滤方式'; + @override String get include => '包含'; + @override String get exclude => '排除'; + @override String get all => '所有'; + @override String get prefer => '优先'; + @override String get only => '仅'; + @override String get open => '打开'; + @override String get close => '关闭'; + @override String get quit => '退出'; + @override String get add => '添加'; + @override String get remove => '删除'; + @override String get edit => '编辑'; + @override String get view => '查看'; + @override String get more => '更多'; + @override String get addProfile => '添加配置'; + @override String get addSuccess => '添加成功'; + @override String addSuccessThen({required Object p}) => '配置生成成功,请到[${p}]查看'; + @override String addFailed({required Object p}) => '添加失败:${p}'; + @override String get removeConfirm => '确认删除?'; + @override String get tips => '提示'; + @override String get copy => '拷贝'; + @override String get ok => '确定'; + @override String get cancel => '取消'; + @override String get feedback => '反馈'; + @override String get faq => '常见问题'; + @override String get download => '下载'; + @override String get loading => '加载中...'; + @override String updateFailed({required Object p}) => '更新失败:${p}'; + @override String get days => '天'; + @override String get hours => '时'; + @override String get minutes => '分'; + @override String get seconds => '秒'; + @override String get protocol => '协议'; + @override String get search => '搜索'; + @override String get custom => '自定义'; + @override String get connect => '连接'; + @override String get disconnect => '断开'; + @override String get connected => '已连接'; + @override String get disconnected => '未连接'; + @override String get connecting => '连接中'; + @override String get connectTimeout => '连接超时'; + @override String get timeout => '超时'; + @override String get language => '语言'; + @override String get next => '下一步'; + @override String get done => '完成'; + @override String get apply => '应用'; + @override String get refresh => '刷新'; + @override String get retry => '是否重试?'; + @override String get none => '无'; + @override String get reset => '重置'; + @override String get submit => '提交'; + @override String get account => '账号'; + @override String get password => '密码'; + @override String get required => '必填'; + @override String get diversion => '分流'; + @override String get diversionRules => '分流规则'; + @override String get diversionRulesEnable => '启用[ISP]分流规则'; + @override String get diversionCustomGroup => '自定义分流组'; + @override String get diversionCustomGroupPreset => '预置[自定义分流组]'; + @override String get diversionCustomGroupPresetTips => '注意:启用的项会添加/覆盖到[自定义分流组]和[分流规则]'; + @override String get diversionCustomGroupAddTips => '注意:添加完毕后可能需要手动调整排序,否则新添加的分流可能不会生效'; + @override String get urlTestCustomGroup => '自定义代理组'; + @override String get rulesetEnableTips => '提示:开启选项后,请到[分流规则]设置相关规则,否则不会生效'; + @override String get ispUserAgentTips => '[ISP]会根据[HTTP]请求里的[UserAgent]下发不同订阅类型的数据'; + @override String get ispDiversionTips => '[ISP]提供的分流规则;[V2Ray]类型的订阅不支持分流规则'; + @override String get staticIP => '静态IP'; + @override String get other => '其他'; + @override String get dns => 'DNS'; + @override String get url => 'URL'; + @override String get isp => 'ISP'; + @override String get tls => 'TLS'; + @override String get userAgent => 'UserAgent'; + @override String get urlInvalid => '无效URL'; + @override String get outboundActionCurrentSelected => '当前选择'; + @override String get outboundActionUrltest => '自动选择'; + @override String get outboundActionDirect => '直连'; + @override String get outboundActionBlock => '拦截'; + @override String get routeFinal => 'final'; + @override String get rulesetGeoSite => 'GeoSite'; + @override String get rulesetGeoIp => 'GeoIP'; + @override String get rulesetAcl => 'ACL'; + @override String get iCloud => 'iCloud'; + @override String get appleTV => 'Apple TV'; + @override String get webdav => 'Webdav'; + @override String get setting => '设置'; + @override String get protocolSniff => '协议探测'; + @override String get protocolSniffOverrideDestination => '探测的域名覆盖连接目标地址'; + @override String get remark => '备注'; + @override String get remarkCannotEmpty => '备注不能为空'; + @override String get remarkTooLong => '备注最长32字符'; + @override String get remarkExist => '备注已存在,请使用其他名称'; + @override String get domainSuffix => '域名后缀'; + @override String get domain => '域名'; + @override String get domainKeyword => '域名关键词'; + @override String get domainRegex => '域名正则'; + @override String get ip => 'IP'; + @override String get port => '端口'; + @override String get appPackage => '应用包名'; + @override String get processName => '进程名称'; + @override String get processPath => '进程路径'; + @override String get systemProxy => '系统代理'; + @override String get netInterfaces => '网络接口'; + @override String get netSpeed => '速度'; + @override String get website => '官网'; + @override String get rule => '规则'; + @override String get global => '全局'; + @override String get qrcode => '二维码'; + @override String get scanQrcode => '扫描二维码'; + @override String get scanResult => '扫描结果'; + @override String get backupAndSync => '备份与同步'; + @override String get importAndExport => '导入/导出'; + @override String get import => '导入'; + @override String get export => '导出'; + @override String get send => '发送'; + @override String get receive => '接收'; + @override String sendOrReceiveNotMatch({required Object p}) => '请使用[${p}]'; + @override String get sendConfirm => '确认发送?'; + @override String get termOfUse => '使用条款'; + @override String get privacyPolicy => '隐私政策'; + @override String get about => '关于'; + @override String get name => '名称'; + @override String get version => '版本'; + @override String get notice => '通知'; + @override String get sort => '排序'; + @override String get novice => '新手模式'; + @override String get recommended => '推荐'; + @override String innerError({required Object p}) => '内部错误:${p}'; + @override String get logicOperation => '逻辑运算'; + @override String get share => '分享'; + @override String get candidateWord => '候选词'; + @override String get keywordOrRegx => '关键词/正则'; + @override String get importFromClipboard => '从剪贴板导入'; + @override String get exportToClipboard => '导出到剪贴板'; + @override String get server => '服务器'; + @override String get appleTVConnectTurnOfprivateDirect => '请先开启[私有网络直连]'; + @override String targetConnectFailed({required Object p}) => '连接[${p}]失败,请确保设备在同一个局域网内,并且开启[私有网络直连]'; + @override String get appleTVSync => '同步当前核心配置到Apple TV - Karing'; + @override String get appleTVSyncDone => '同步完成,请到Apple TV - Karing开启连接/重启连接'; + @override String get appleTVRemoveCoreConfig => '删除Apple TV - Karing核心配置'; + @override String get appleTVRemoveCoreConfigDone => 'Apple TV - Karing的核心配置文件已删除;VPN服务已断开连接'; + @override String get appleTVUrlInvalid => '无效的URL,请打开Apple TV - Karing,扫描Karing显示的二维码'; + @override String get remoteProfileEditConfirm => '配置更新后,节点的修改将会被还原,是否继续?'; + @override String invalidFileType({required Object p}) => '无效的文件类型:${p}'; + @override String get mustBeValidHttpsURL => '必须为有效的 https URL'; + @override String fileNotExistReinstall({required Object p}) => '文件缺失[${p}],请重新安装'; + @override String get latencyTest => '延迟检测'; + @override String get latencyTestResolveIP => '手动检测时,同时解析出口IP'; + @override String get uwpExemption => 'UWP网络隔离豁免'; + @override String get removeBannerAds => '去除广告'; + @override String get removeBannerAdsByReward => '观看一段数秒广告,将会获得7天无广告奖励'; + @override String get removeBannerAdsByRewardDone => '已获得7天无广告奖励'; + @override Map get locales => { + 'en': 'English', + 'zh-CN': '简体中文', + 'ar': 'عربي', + 'ru': 'Русский', + 'fa': 'فارسی', + }; +} + +// Path: AboutScreen +class _TranslationsAboutScreenZhCn implements TranslationsAboutScreenEn { + _TranslationsAboutScreenZhCn._(this._root); + + final TranslationsZhCn _root; // ignore: unused_field + + // Translations + @override String get installRefer => '安装参考'; + @override String get versionChannel => '自动更新通道'; + @override String get disableUAReport => '关闭行为数据上报'; + @override String get disableUAReportTip => '行为数据上报有助于我们改进产品体验;低于主版本的版本将自动关闭的所有数据上报([应用激活]除外)'; + @override String get devOptions => '开发者选项'; + @override String get enableDebugLog => '开启调试日志'; + @override String get viewFilsContent => '查看文件'; + @override String get enablePprof => '启用pprof'; + @override String get pprofPanel => 'pprof面板'; + @override String get openDir => '打开文件目录'; + @override String get useOriginalSBProfile => '使用原始sing-box配置'; +} + +// Path: AddProfileByImportFromFileScreen +class _TranslationsAddProfileByImportFromFileScreenZhCn implements TranslationsAddProfileByImportFromFileScreenEn { + _TranslationsAddProfileByImportFromFileScreenZhCn._(this._root); + + final TranslationsZhCn _root; // ignore: unused_field + + // Translations + @override String get title => '导入配置文件'; + @override String get chooseFile => '选择文件'; + @override String get configExist => '配置已存在,请勿重复添加'; +} + +// Path: AddProfileByLinkOrContentScreen +class _TranslationsAddProfileByLinkOrContentScreenZhCn implements TranslationsAddProfileByLinkOrContentScreenEn { + _TranslationsAddProfileByLinkOrContentScreenZhCn._(this._root); + + final TranslationsZhCn _root; // ignore: unused_field + + // Translations + @override String get title => '添加配置链接'; + @override String get updateTimerInterval => '更新时间间隔'; + @override String get updateTimerIntervalTips => '最小:5m'; + @override String get profileLinkContent => '配置链接/内容'; + @override String get profileLinkContentHit => '配置链接/内容[必填] (支持Clash,V2ray(支持批量),Stash,Karing,Sing-box,Shadowsocks,Sub,Github配置链接)'; + @override String get subscriptionCannotEmpty => '配置链接不能为空'; + @override String get configExist => '配置已存在,请勿重复添加'; + @override String get invalidUrl => '配置链接长度过长'; + @override String addFailedFormatException({required Object p}) => '格式错误,请订正后重新添加:${p}'; + @override String addFailedThenDownloadAndImport({required Object p}) => '添加失败:${p}, 请尝试修改[UserAgent]后重试,或者用设备自带的浏览器打开配置链接,并将浏览器下载的配置文件导入到本应用'; + @override String addFailedHandshakeException({required Object p}) => '添加失败:${p}, 请打开代理或者修改当前代理节点后重试'; +} + +// Path: AddProfileByScanQrcodeScanScreen +class _TranslationsAddProfileByScanQrcodeScanScreenZhCn implements TranslationsAddProfileByScanQrcodeScanScreenEn { + _TranslationsAddProfileByScanQrcodeScanScreenZhCn._(this._root); + + final TranslationsZhCn _root; // ignore: unused_field + + // Translations + @override String get copy => '拷贝链接'; + @override String get open => '打开链接'; + @override String get requestCameraPermission => '请开启摄像头权限'; + @override String get requestScreenAccess => '请到系统设置-隐私与安全-屏幕录制 为本应用添加权限'; + @override String get screenshot => '截图'; + @override String get scanFromImage => '打开二维码图片'; + @override String get scanNoResult => '解析图片失败,请确保截图为有效的二维码'; + @override String get scanEmptyResult => '扫描结果为空'; + @override String scanException({required Object p}) => '解析图片异常,请确保截图为有效的二维码:${p}'; +} + +// Path: BackupAndSyncLanSyncScreen +class _TranslationsBackupAndSyncLanSyncScreenZhCn implements TranslationsBackupAndSyncLanSyncScreenEn { + _TranslationsBackupAndSyncLanSyncScreenZhCn._(this._root); + + final TranslationsZhCn _root; // ignore: unused_field + + // Translations + @override String get title => '局域网同步'; + @override String get lanSyncNotQuitTips => '同步完成前请勿退出此界面'; +} + +// Path: BackupAndSyncWebdavScreen +class _TranslationsBackupAndSyncWebdavScreenZhCn implements TranslationsBackupAndSyncWebdavScreenEn { + _TranslationsBackupAndSyncWebdavScreenZhCn._(this._root); + + final TranslationsZhCn _root; // ignore: unused_field + + // Translations + @override String get webdavServerUrl => '服务器地址'; + @override String get webdavRequired => '不能为空'; + @override String get webdavLoginFailed => '登录失败:'; + @override String get webdavListFailed => '获取文件列表失败:'; +} + +// Path: DiversionGroupCustomEditScreen +class _TranslationsDiversionGroupCustomEditScreenZhCn implements TranslationsDiversionGroupCustomEditScreenEn { + _TranslationsDiversionGroupCustomEditScreenZhCn._(this._root); + + final TranslationsZhCn _root; // ignore: unused_field + + // Translations + @override String invalidDomain({required Object p}) => '无效的 [Domain]:${p}'; + @override String invalidIpCidr({required Object p}) => '无效的 [IP Cidr]:${p}'; + @override String invalidPort({required Object p}) => '无效的 [Port]:${p}'; + @override String invalidRuleSet({required Object p}) => '无效的 [Rule Set]:${p}, URL必须是有效的https URL,并且文件扩展名为.srs/.json的binary文件'; + @override String invalidRuleSetBuildIn({required Object p}) => '无效的 [Rule Set(build-in)]:${p}, 格式为geosite:xxx 或 geoip:xxx 或 acl:xxx,并且xxx应为有效的规则名'; + @override String get setDiversionRule => '提示:保存后,请到[分流规则]设置相关规则,否则不会生效'; +} + +// Path: DiversionRuleDetectScreen +class _TranslationsDiversionRuleDetectScreenZhCn implements TranslationsDiversionRuleDetectScreenEn { + _TranslationsDiversionRuleDetectScreenZhCn._(this._root); + + final TranslationsZhCn _root; // ignore: unused_field + + // Translations + @override String get title => '分流规则探测'; + @override String get detect => '探测'; + @override String get rule => '规则:'; + @override String get outbound => '代理服务器:'; +} + +// Path: DiversionRulesScreen +class _TranslationsDiversionRulesScreenZhCn implements TranslationsDiversionRulesScreenEn { + _TranslationsDiversionRulesScreenZhCn._(this._root); + + final TranslationsZhCn _root; // ignore: unused_field + + // Translations + @override String get diversionRulesMatchTips => '提示:从上到下依次尝试匹配规则,如果没有匹配到规则,则使用[final]'; +} + +// Path: DnsSettingsScreen +class _TranslationsDnsSettingsScreenZhCn implements TranslationsDnsSettingsScreenEn { + _TranslationsDnsSettingsScreenZhCn._(this._root); + + final TranslationsZhCn _root; // ignore: unused_field + + // Translations + @override String get ispCanNotEmpty => 'ISP 不能为空'; + @override String get urlCanNotEmpty => 'URL 不能为空'; + @override String error({required Object p}) => '不支持的类型:${p}'; + @override String get dnsDesc => '第一列延迟数据为直连查询延迟;\n第二列:开启[[代理流量]通过代理服务器解析DNS]:延迟数据为通过当前代理服务器转发的查询延迟;未开启[[代理流量]通过代理服务器解析DNS]:延迟数据为直连查询延迟'; +} + +// Path: FeedbackScreen +class _TranslationsFeedbackScreenZhCn implements TranslationsFeedbackScreenEn { + _TranslationsFeedbackScreenZhCn._(this._root); + + final TranslationsZhCn _root; // ignore: unused_field + + // Translations + @override String get content => '反馈内容'; + @override String get contentHit => '必填, 最长500字符'; + @override String get contentCannotEmpty => '反馈内容不能为空'; +} + +// Path: FileContentViewerScreen +class _TranslationsFileContentViewerScreenZhCn implements TranslationsFileContentViewerScreenEn { + _TranslationsFileContentViewerScreenZhCn._(this._root); + + final TranslationsZhCn _root; // ignore: unused_field + + // Translations + @override String get title => '文件内容查看'; + @override String get chooseFile => '选择文件'; + @override String get clearFileContent => '确认清空文件内容?'; + @override String get clearFileContentTips => '确认清空配置文件内容? 清空配置文件可能会导致数据丢失或应用功能异常, 请谨慎操作'; +} + +// Path: HomeScreen +class _TranslationsHomeScreenZhCn implements TranslationsHomeScreenEn { + _TranslationsHomeScreenZhCn._(this._root); + + final TranslationsZhCn _root; // ignore: unused_field + + // Translations + @override String get toSelectServer => '请选择服务器'; + @override String get invalidServer => '已失效,请重新选择'; + @override String get disabledServer => '已被禁用,请重新选择'; + @override String get expiredServer => '无可用服务器:配置可能已过期或被禁用'; + @override String systemProxyTips({required Object sp, required Object hp}) => 'socks:${sp},http(s):${hp}'; + @override String get trafficTotal => '总流量'; + @override String get trafficProxy => '代理流量'; + @override String get myLinkEmpty => '请先设置[快捷链接]后再使用'; + @override String get deviceNoSpace => '磁盘空间不足'; + @override String tooMuchServers({required Object p, required Object p1}) => '代理服务器[${p}>${p1}]过多,可能因系统内存限制而无法连接'; +} + +// Path: LaunchFailedScreen +class _TranslationsLaunchFailedScreenZhCn implements TranslationsLaunchFailedScreenEn { + _TranslationsLaunchFailedScreenZhCn._(this._root); + + final TranslationsZhCn _root; // ignore: unused_field + + // Translations + @override String get invalidProcess => '应用启动失败[无效的进程名称],请重新安装应用到独立目录'; + @override String get invalidProfile => '应用启动失败[访问配置文件失败],请重新安装应用'; + @override String get invalidVersion => '应用启动失败[无效版本],请重新安装应用'; + @override String get systemVersionLow => '应用启动失败[系统版本过低]'; + @override String get invalidInstallPath => '无效的安装路径,请重新安装到有效路径'; +} + +// Path: MyProfilesEditScreen +class _TranslationsMyProfilesEditScreenZhCn implements TranslationsMyProfilesEditScreenEn { + _TranslationsMyProfilesEditScreenZhCn._(this._root); + + final TranslationsZhCn _root; // ignore: unused_field + + // Translations + @override String get title => '编辑配置'; + @override String get urlExist => 'URL已存在,请使用其他URL'; + @override String get updateTimerInterval => '更新时间间隔'; + @override String get updateTimerIntervalTips => '最小:5m'; + @override String get reloadAfterProfileUpdate => '配置更新后重新加载'; + @override String get testLatencyAfterProfileUpdate => '配置自动更新后启动延迟测试'; + @override String get testLatencyAfterProfileUpdateTips => 'VPN需要处于已连接状态,并且开启[配置更新后重新加载]'; + @override String get testLatencyAutoRemove => '自动移除延迟测试失败的服务器'; + @override String get testLatencyAutoRemoveTips => '最多尝试3次'; +} + +// Path: MyProfilesMergeScreen +class _TranslationsMyProfilesMergeScreenZhCn implements TranslationsMyProfilesMergeScreenEn { + _TranslationsMyProfilesMergeScreenZhCn._(this._root); + + final TranslationsZhCn _root; // ignore: unused_field + + // Translations + @override String get profilesMerge => '配置合并'; + @override String get profilesMergeTarget => '目标配置'; + @override String get profilesMergeSource => '源配置'; + @override String get profilesMergeTips => '提示:源配置的分流信息将会被丢弃'; +} + +// Path: MyProfilesScreen +class _TranslationsMyProfilesScreenZhCn implements TranslationsMyProfilesScreenEn { + _TranslationsMyProfilesScreenZhCn._(this._root); + + final TranslationsZhCn _root; // ignore: unused_field + + // Translations + @override String get title => '我的配置'; + @override String get atLeastOneEnable => '无法禁用,请至少保留一个配置可用'; +} + +// Path: NetCheckScreen +class _TranslationsNetCheckScreenZhCn implements TranslationsNetCheckScreenEn { + _TranslationsNetCheckScreenZhCn._(this._root); + + final TranslationsZhCn _root; // ignore: unused_field + + // Translations + @override String get title => '网络检测'; + @override String get warn => '注意:由于受网络环境及分流规则等影响,测试结果并不完全等价实际中使用的效果'; + @override String get check => '检测'; + @override String get invalidDomain => '无效域名'; + @override String get connectivity => '网络联通性'; + @override String connectivityTestIpv4AllFailed({required Object p}) => 'Ipv4 连接测试[${p}]全部失败'; + @override String get connectivityTestIpv4Ok => 'Ipv4 连接成功'; + @override String connectivityTestIpv6AllFailed({required Object p}) => 'Ipv6 连接测试[${p}]全部失败, 你的网络可能不支持ipv6'; + @override String get connectivityTestIpv6Ok => 'Ipv6 连接成功'; + @override String get connectivityTestOk => '网络已接入互联网'; + @override String get connectivityTestFailed => '网络尚未接入互联网'; + @override String get remoteRulesetsDownloadOk => '全部下载成功'; + @override String get remoteRulesetsDownloadNotOk => '正在下载或下载失败'; + @override String get outbound => '代理服务器'; + @override String outboundOk({required Object p}) => '[${p}]连接成功'; + @override String outboundFailed({required Object p1, required Object p2}) => '[${p1}]连接失败\n错误:[${p2}]'; + @override String get dnsServer => 'DNS服务器'; + @override String dnsOk({required Object p1, required Object p2, required Object p3, required Object p4}) => '[${p1}]域名解析成功\nDNS规则:[${p2}]\n延迟:[${p3} ms]\n地址:[${p4}]'; + @override String dnsFailed({required Object p1, required Object p2, required Object p3}) => '[${p1}]域名解析失败\n规则:[${p2}]\n错误:[${p3}]'; + @override String get host => 'HTTP连接'; + @override String hostConnection({required Object p1, required Object p2, required Object p3}) => '[${p1}]\n分流规则:[${p2}]\n代理服务器:[${p3}]'; + @override String get hostConnectionOk => '连接成功'; + @override String hostConnectionFailed({required Object p}) => '连接失败:[${p}]'; +} + +// Path: NetConnectionsFilterScreen +class _TranslationsNetConnectionsFilterScreenZhCn implements TranslationsNetConnectionsFilterScreenEn { + _TranslationsNetConnectionsFilterScreenZhCn._(this._root); + + final TranslationsZhCn _root; // ignore: unused_field + + // Translations + @override String get title => '连接状态筛选'; + @override String get hostIp => '域名/IP'; + @override String get app => '应用'; + @override String get rule => '规则'; + @override String get chain => '出站'; +} + +// Path: NetConnectionsScreen +class _TranslationsNetConnectionsScreenZhCn implements TranslationsNetConnectionsScreenEn { + _TranslationsNetConnectionsScreenZhCn._(this._root); + + final TranslationsZhCn _root; // ignore: unused_field + + // Translations + @override String get title => '连接状态'; + @override String get copyAsCSV => '已复制为CSV格式'; + @override String get selectType => '选择分流类型'; +} + +// Path: PerAppAndroidScreen +class _TranslationsPerAppAndroidScreenZhCn implements TranslationsPerAppAndroidScreenEn { + _TranslationsPerAppAndroidScreenZhCn._(this._root); + + final TranslationsZhCn _root; // ignore: unused_field + + // Translations + @override String get title => '分应用代理'; + @override String get whiteListMode => '白名单模式'; + @override String get whiteListModeTip => '启用后:仅代理已勾选的App;未启用:仅代理未勾选的App'; + @override String get hideSystemApp => '隐藏系统应用'; + @override String get hideAppIcon => '隐藏应用图标'; + @override String get enableAppQueryPermission => '开启 [获取应用列表] 权限'; +} + +// Path: QrcodeScreen +class _TranslationsQrcodeScreenZhCn implements TranslationsQrcodeScreenEn { + _TranslationsQrcodeScreenZhCn._(this._root); + + final TranslationsZhCn _root; // ignore: unused_field + + // Translations + @override String get tooLong => '文本过长,无法展示'; + @override String get copy => '拷贝链接'; + @override String get open => '打开链接'; + @override String get share => '分享链接'; + @override String get shareImage => '分享二维码'; +} + +// Path: RegionSettingsScreen +class _TranslationsRegionSettingsScreenZhCn implements TranslationsRegionSettingsScreenEn { + _TranslationsRegionSettingsScreenZhCn._(this._root); + + final TranslationsZhCn _root; // ignore: unused_field + + // Translations + @override String get title => '国家与地区'; + @override String get Regions => '提示:请正确设置你当前所在国家或地区,否则可能会导致分流错误'; +} + +// Path: ServerSelectScreen +class _TranslationsServerSelectScreenZhCn implements TranslationsServerSelectScreenEn { + _TranslationsServerSelectScreenZhCn._(this._root); + + final TranslationsZhCn _root; // ignore: unused_field + + // Translations + @override String get title => '选择服务器'; + @override String get autoSelectServer => '自动选择延迟最低的服务器'; + @override String get recentUse => '最近使用'; + @override String get myFav => '我的收藏'; + @override String selectLocal({required Object p}) => '所选服务器为本地地址,可能无法正常使用:${p}'; + @override String get selectRequireEnableIPv6 => '所选服务器为IPv6地址,需要[启用IPv6]'; + @override String get selectDisabled => '该服务器已被禁用'; + @override String get error404 => '延迟检测遇到错误,请检查是否存在内容相同的配置'; +} + +// Path: SettingsScreen +class _TranslationsSettingsScreenZhCn implements TranslationsSettingsScreenEn { + _TranslationsSettingsScreenZhCn._(this._root); + + final TranslationsZhCn _root; // ignore: unused_field + + // Translations + @override String ispFaq({required Object p}) => 'FAQ[${p}]'; + @override String cleanISP({required Object p}) => '清除ISP[${p}]'; + @override String get openISP => '打开ISP链接'; + @override String get cleanISPNoParam => '清除ISP信息'; + @override String get getTranffic => '获取流量'; + @override String get tutorial => '使用教程'; + @override String get commonlyUsedRulesets => '常用规则集'; + @override String get howToRemoveAds => '如何移除广告'; + @override String get htmlBoard => '在线面板'; + @override String get dnsLeakDetection => 'DNS泄露检测'; + @override String get speedTest => '测速'; + @override String get downloadProfilePreferProxy => '优先使用代理下载配置'; + @override String get downloadProfilePreferProxyTips => '如果当前已连接,则优先通过已连接的代理下载配置'; + @override String get rulesetDirectDownlad => 'Rule Set直连下载'; + @override String get hideUnusedDiversionGroup => '隐藏未启用的分流组'; + @override String get disableISPDiversionGroup => '禁用ISP分流规则'; + @override String get portSetting => '端口'; + @override String get portSettingRule => '基于规则'; + @override String get portSettingDirectAll => '全直连'; + @override String get portSettingProxyAll => '全代理'; + @override String get portSettingControl => '控制与同步'; + @override String get portSettingCluster => '集群服务'; + @override String get modifyPort => '修改端口'; + @override String get modifyPortOccupied => '端口已被占用,请使用其他端口'; + @override String get ipStrategyTips => '启用前,请先确认你的网络已支持IPv6,否则某些流量无法正常访问'; + @override String get tunAppendHttpProxy => '附加HTTP代理到VPN'; + @override String get tunAppendHttpProxyTips => '一些App会绕过虚拟网卡设备直连HTTP代理'; + @override String get tlsInsecureEnable => '跳过证书验证'; + @override String get tlsFragmentEnable => '启用TLS分段'; + @override String get tlsFragmentSize => 'TLS分段大小'; + @override String get tlsFragmentSleep => 'TLS分段休眠'; + @override String get tlsMixedCaseSNIEnable => '启用TLS混合SNI'; + @override String get tlsPaddingEnable => '启用TLS填充'; + @override String get tlsPaddingSize => 'TLS填充大小'; + @override String get dnsEnableRule => '启用DNS分流规则'; + @override String get dnsEnableFakeIp => '启用FakeIP'; + @override String get dnsEnableClientSubnet => '启用ECS'; + @override String get dnsEnableProxyResolveByProxy => '[代理流量]通过代理服务器解析DNS'; + @override String get dnsEnableFinalResolveByProxy => '[final]通过代理服务器解析DNS'; + @override String get dnsTestDomain => '测试域名'; + @override String get dnsTestDomainInvalid => '无效的域名'; + @override String get dnsTypeOutbound => '代理服务器'; + @override String get dnsTypeDirect => '直连流量'; + @override String get dnsTypeProxy => '代理流量'; + @override String get dnsTypeResolver => 'DNS服务器'; + @override String get dnsEnableRuleTips => '启用后,域名会根据分流规则选择对应的DNS服务器进行解析'; + @override String get dnsEnableFakeIpTips => '启用FakeIP后,如果断开VPN连接,你的应用可能需要重启;此功能需要开启[TUN模式]'; + @override String get dnsTypeOutboundTips => '用于代理服务器的域名解析'; + @override String get dnsTypeDirectTips => '用于直连流量的域名解析'; + @override String get dnsTypeProxyTips => '用于代理流量的域名解析'; + @override String get dnsTypeResolverTips => '用于DNS服务器的域名解析'; + @override String get dnsTypeFinalTips => '用于其他流量的域名解析'; + @override String get dnsAutoSetServer => '自动设置服务器'; + @override String get dnsResetServer => '重置服务器'; + @override String get inboundDomainResolve => '解析入站域名'; + @override String get privateDirect => '私有网络直连'; + @override String inboundDomainResolveTips({required Object p}) => '某些未配置分流规则的域名需要解析后才可能命中基于IP的分流规则;此功能影响代理端口[${p}]的入站请求'; + @override String get useRomoteRes => '使用远程资源'; + @override String get autoSelect => '自动选择'; + @override String get autoSelectServerIgnorePerProxyServer => '忽略[前置代理]代理服务器'; + @override String get autoSelectServerInterval => '延迟检测时间间隔'; + @override String get autoSelectServerReTestIfNetworkUpdate => '网络变化时重新检测'; + @override String get autoSelectServerUpdateCurrentServerAfterManualUrltest => '手动延时检测后更新当前服务器'; + @override String get autoSelectServerIntervalTips => '延迟检测时间间隔越短,服务器延迟数据更新越及时,但会占用更多资源,耗电更快'; + @override String get autoSelectServerFavFirst => '优先使用[我的收藏]'; + @override String get autoSelectServerFavFirstTips => '如果[我的收藏]列表不为空,则使用[我的收藏]里的服务器'; + @override String get autoSelectServerFilter => '过滤无效服务器'; + @override String autoSelectServerFilterTips({required Object p}) => '服务器延迟检测失败的将会被过滤掉;如果过滤后无服务器可用,则改用前[${p}]个服务器'; + @override String get autoSelectServerLimitedNum => '服务器数量上限'; + @override String get autoSelectServerLimitedNumTips => '超过该数量的服务器将被过滤掉'; + @override String get numInvalid => '无效的数字'; + @override String get hideInvalidServer => '隐藏无效服务器'; + @override String get sortServer => '服务器排序'; + @override String get sortServerTips => '按延迟由低到高排序'; + @override String get selectServerHideRecommand => '隐藏[推荐]'; + @override String get selectServerHideRecent => '隐藏[最近使用]'; + @override String get selectServerHideFav => '隐藏[我的收藏]'; + @override String get homeScreen => '主屏'; + @override String get theme => '主题'; + @override String get myLink => '快捷链接'; + @override String get myLinkInvalid => '无效的URL'; + @override String get autoConnectAfterLaunch => '启动后自动连接'; + @override String get hideAfterLaunch => '启动后隐藏窗口'; + @override String get autoSetSystemProxy => '连接后自动设置系统代理'; + @override String get disconnectWhenQuit => '退出应用时关闭连接'; + @override String get allowBypass => '允许应用绕过VPN'; + @override String get importSuccess => '导入成功'; + @override String get rewriteConfirm => '该文件将覆盖本地已有配置,是否继续?'; + @override String get networkShare => '网络共享'; + @override String get frontProxy => '前置代理'; + @override String frontProxyTips({required Object p}) => '数据->前置代理服务器[多个前置代理服务器:由上到下]->代理服务器[${p}]->目标服务器'; + @override String get allowOtherHostsConnect => '允许其他主机接入'; + @override String allowOtherHostsConnectTips({required Object sp, required Object hp}) => 'socks:${sp},http(s):${hp}'; + @override String get tunAutoRoute => 'Auto Route'; + @override String get tunStrictRoute => '严格路由'; + @override String get tunStrictRouteTips => '如果开启共享后,其他无法接入此设备,请尝试关闭此开关'; + @override String get enableCluster => '开启Socks/Http代理集群'; + @override String get clusterAllowOtherHostsConnect => '允许其他主机接入代理集群'; + @override String clusterAllowOtherHostsConnectTips({required Object ip, required Object port}) => 'http://${ip}:${port}/get_proxies'; + @override String get clusterAuth => '代理集群认证'; + @override String get tunMode => 'TUN模式'; + @override String get tunModeTips => 'TUN模式将接管系统所有流量[此模式下无需开启系统代理]'; + @override String get tunModeRunAsAdmin => 'TUN模式需要系统管理员权限,请以管理员身份重新启动应用'; + @override String get tunStack => '网络栈'; + @override String get launchAtStartup => '开机启动'; + @override String get quitWhenSwitchSystemUser => '切换系统用户时退出应用'; + @override String get handleScheme => '系统Scheme调用'; + @override String get portableMode => '便携模式'; + @override String get portableModeDisableTips => '如需退出便携模式,请退出[karing]后,手动删除[karing.exe]同目录下的[profiles]文件夹即可'; + @override String get handleKaringScheme => '处理karing://调用'; + @override String get handleClashScheme => '处理clash://调用'; + @override String get handleSingboxScheme => '处理sing-box://调用'; + @override String get alwayOnVPN => '始终开启连接'; + @override String get removeSystemVPNConfig => '删除系统VPN配置'; + @override String get timeConnectOrDisconnect => '定时连接/断开'; + @override String get timeConnectOrDisconnectTips => 'VPN必须处于连接状态才会生效;开启后,[自动休眠]将失效'; + @override String timeConnectAndDisconnectInterval({required Object p}) => '连接/断开时间间隔不能低于${p}分钟'; + @override String get disableFontScaler => '禁用字体缩放'; + @override String get autoOrientation => '跟随屏幕旋转'; + @override String get restartTakesEffect => '重启生效'; + @override String get resetSettings => '重置设置'; + @override String get cleanCache => '清理缓存'; + @override String get cleanCacheDone => '清理完成'; + @override String get appleTestFlight => '苹果 TestFlight'; + @override String get appleAppStore => '苹果 AppStore'; + @override String hasNewVersion({required Object p}) => '更新版本 ${p}'; + @override String get follow => '关注我们'; + @override String get contactUs => '联系我们'; + @override String get rateInApp => '评分'; + @override String get rateInAppStore => '在App Store上评分'; +} + +// Path: SpeedTestSettingsScreen +class _TranslationsSpeedTestSettingsScreenZhCn implements TranslationsSpeedTestSettingsScreenEn { + _TranslationsSpeedTestSettingsScreenZhCn._(this._root); + + final TranslationsZhCn _root; // ignore: unused_field + + // Translations + @override String get title => '测速URL'; +} + +// Path: TextToQrCodeScreen +class _TranslationsTextToQrCodeScreenZhCn implements TranslationsTextToQrCodeScreenEn { + _TranslationsTextToQrCodeScreenZhCn._(this._root); + + final TranslationsZhCn _root; // ignore: unused_field + + // Translations + @override String get title => '文本转二维码'; + @override String get convert => '转换'; +} + +// Path: UserAgreementScreen +class _TranslationsUserAgreementScreenZhCn implements TranslationsUserAgreementScreenEn { + _TranslationsUserAgreementScreenZhCn._(this._root); + + final TranslationsZhCn _root; // ignore: unused_field + + // Translations + @override String get privacyFirst => '您的隐私很重要'; + @override String get agreeAndContinue => '接受并继续'; +} + +// Path: VersionUpdateScreen +class _TranslationsVersionUpdateScreenZhCn implements TranslationsVersionUpdateScreenEn { + _TranslationsVersionUpdateScreenZhCn._(this._root); + + final TranslationsZhCn _root; // ignore: unused_field + + // Translations + @override String versionReady({required Object p}) => '新版本[${p}]已就绪'; + @override String get update => '重启更新'; + @override String get cancel => '暂不更新'; +} + +// Path: CommonWidget +class _TranslationsCommonWidgetZhCn implements TranslationsCommonWidgetEn { + _TranslationsCommonWidgetZhCn._(this._root); + + final TranslationsZhCn _root; // ignore: unused_field + + // Translations + @override String get diableAlwayOnVPN => '如果开启了[始终开启VPN], 请关闭[始终开启VPN]后重试连接'; + @override String get resetPort => '请将端口改为其他可用端口或者关闭占用该端口的应用'; +} + +// Path: ServerManager +class _TranslationsServerManagerZhCn implements TranslationsServerManagerEn { + _TranslationsServerManagerZhCn._(this._root); + + final TranslationsZhCn _root; // ignore: unused_field + + // Translations + @override String get noServerAvaliable => '无可用服务器,请确保配置链接或配置文件有效;如果你的配置来源于GitHub,请从页面上的[Raw]按钮获取链接地址'; + @override String get filePathCannotEmpty => '文件路径不能为空'; + @override String fileNotExist({required Object p}) => '文件不存在:${p}'; + @override String get urlCannotEmpty => '链接不能为空'; + @override String get invalidUrl => '错误的配置链接'; + @override String get parseFailed => '解析配置失败'; +} + +// Path: main +class _TranslationsMainZhCn implements TranslationsMainEn { + _TranslationsMainZhCn._(this._root); + + final TranslationsZhCn _root; // ignore: unused_field + + // Translations + @override late final _TranslationsMainTrayZhCn tray = _TranslationsMainTrayZhCn._(_root); +} + +// Path: main.tray +class _TranslationsMainTrayZhCn implements TranslationsMainTrayEn { + _TranslationsMainTrayZhCn._(this._root); + + final TranslationsZhCn _root; // ignore: unused_field + + // Translations + @override String get menuOpen => ' 打开 '; + @override String get menuExit => ' 退出 '; +} + +/// Flat map(s) containing all translations. +/// Only for edge cases! For simple maps, use the map function of this library. +extension on TranslationsZhCn { + dynamic _flatMapFunction(String path) { + switch (path) { + case 'AboutScreen.installRefer': return '安装参考'; + case 'AboutScreen.versionChannel': return '自动更新通道'; + case 'AboutScreen.disableUAReport': return '关闭行为数据上报'; + case 'AboutScreen.disableUAReportTip': return '行为数据上报有助于我们改进产品体验;低于主版本的版本将自动关闭的所有数据上报([应用激活]除外)'; + case 'AboutScreen.devOptions': return '开发者选项'; + case 'AboutScreen.enableDebugLog': return '开启调试日志'; + case 'AboutScreen.viewFilsContent': return '查看文件'; + case 'AboutScreen.enablePprof': return '启用pprof'; + case 'AboutScreen.pprofPanel': return 'pprof面板'; + case 'AboutScreen.openDir': return '打开文件目录'; + case 'AboutScreen.useOriginalSBProfile': return '使用原始sing-box配置'; + case 'AddProfileByImportFromFileScreen.title': return '导入配置文件'; + case 'AddProfileByImportFromFileScreen.chooseFile': return '选择文件'; + case 'AddProfileByImportFromFileScreen.configExist': return '配置已存在,请勿重复添加'; + case 'AddProfileByLinkOrContentScreen.title': return '添加配置链接'; + case 'AddProfileByLinkOrContentScreen.updateTimerInterval': return '更新时间间隔'; + case 'AddProfileByLinkOrContentScreen.updateTimerIntervalTips': return '最小:5m'; + case 'AddProfileByLinkOrContentScreen.profileLinkContent': return '配置链接/内容'; + case 'AddProfileByLinkOrContentScreen.profileLinkContentHit': return '配置链接/内容[必填] (支持Clash,V2ray(支持批量),Stash,Karing,Sing-box,Shadowsocks,Sub,Github配置链接)'; + case 'AddProfileByLinkOrContentScreen.subscriptionCannotEmpty': return '配置链接不能为空'; + case 'AddProfileByLinkOrContentScreen.configExist': return '配置已存在,请勿重复添加'; + case 'AddProfileByLinkOrContentScreen.invalidUrl': return '配置链接长度过长'; + case 'AddProfileByLinkOrContentScreen.addFailedFormatException': return ({required Object p}) => '格式错误,请订正后重新添加:${p}'; + case 'AddProfileByLinkOrContentScreen.addFailedThenDownloadAndImport': return ({required Object p}) => '添加失败:${p}, 请尝试修改[UserAgent]后重试,或者用设备自带的浏览器打开配置链接,并将浏览器下载的配置文件导入到本应用'; + case 'AddProfileByLinkOrContentScreen.addFailedHandshakeException': return ({required Object p}) => '添加失败:${p}, 请打开代理或者修改当前代理节点后重试'; + case 'AddProfileByScanQrcodeScanScreen.copy': return '拷贝链接'; + case 'AddProfileByScanQrcodeScanScreen.open': return '打开链接'; + case 'AddProfileByScanQrcodeScanScreen.requestCameraPermission': return '请开启摄像头权限'; + case 'AddProfileByScanQrcodeScanScreen.requestScreenAccess': return '请到系统设置-隐私与安全-屏幕录制 为本应用添加权限'; + case 'AddProfileByScanQrcodeScanScreen.screenshot': return '截图'; + case 'AddProfileByScanQrcodeScanScreen.scanFromImage': return '打开二维码图片'; + case 'AddProfileByScanQrcodeScanScreen.scanNoResult': return '解析图片失败,请确保截图为有效的二维码'; + case 'AddProfileByScanQrcodeScanScreen.scanEmptyResult': return '扫描结果为空'; + case 'AddProfileByScanQrcodeScanScreen.scanException': return ({required Object p}) => '解析图片异常,请确保截图为有效的二维码:${p}'; + case 'BackupAndSyncLanSyncScreen.title': return '局域网同步'; + case 'BackupAndSyncLanSyncScreen.lanSyncNotQuitTips': return '同步完成前请勿退出此界面'; + case 'BackupAndSyncWebdavScreen.webdavServerUrl': return '服务器地址'; + case 'BackupAndSyncWebdavScreen.webdavRequired': return '不能为空'; + case 'BackupAndSyncWebdavScreen.webdavLoginFailed': return '登录失败:'; + case 'BackupAndSyncWebdavScreen.webdavListFailed': return '获取文件列表失败:'; + case 'DiversionGroupCustomEditScreen.invalidDomain': return ({required Object p}) => '无效的 [Domain]:${p}'; + case 'DiversionGroupCustomEditScreen.invalidIpCidr': return ({required Object p}) => '无效的 [IP Cidr]:${p}'; + case 'DiversionGroupCustomEditScreen.invalidPort': return ({required Object p}) => '无效的 [Port]:${p}'; + case 'DiversionGroupCustomEditScreen.invalidRuleSet': return ({required Object p}) => '无效的 [Rule Set]:${p}, URL必须是有效的https URL,并且文件扩展名为.srs/.json的binary文件'; + case 'DiversionGroupCustomEditScreen.invalidRuleSetBuildIn': return ({required Object p}) => '无效的 [Rule Set(build-in)]:${p}, 格式为geosite:xxx 或 geoip:xxx 或 acl:xxx,并且xxx应为有效的规则名'; + case 'DiversionGroupCustomEditScreen.setDiversionRule': return '提示:保存后,请到[分流规则]设置相关规则,否则不会生效'; + case 'DiversionRuleDetectScreen.title': return '分流规则探测'; + case 'DiversionRuleDetectScreen.detect': return '探测'; + case 'DiversionRuleDetectScreen.rule': return '规则:'; + case 'DiversionRuleDetectScreen.outbound': return '代理服务器:'; + case 'DiversionRulesScreen.diversionRulesMatchTips': return '提示:从上到下依次尝试匹配规则,如果没有匹配到规则,则使用[final]'; + case 'DnsSettingsScreen.ispCanNotEmpty': return 'ISP 不能为空'; + case 'DnsSettingsScreen.urlCanNotEmpty': return 'URL 不能为空'; + case 'DnsSettingsScreen.error': return ({required Object p}) => '不支持的类型:${p}'; + case 'DnsSettingsScreen.dnsDesc': return '第一列延迟数据为直连查询延迟;\n第二列:开启[[代理流量]通过代理服务器解析DNS]:延迟数据为通过当前代理服务器转发的查询延迟;未开启[[代理流量]通过代理服务器解析DNS]:延迟数据为直连查询延迟'; + case 'FeedbackScreen.content': return '反馈内容'; + case 'FeedbackScreen.contentHit': return '必填, 最长500字符'; + case 'FeedbackScreen.contentCannotEmpty': return '反馈内容不能为空'; + case 'FileContentViewerScreen.title': return '文件内容查看'; + case 'FileContentViewerScreen.chooseFile': return '选择文件'; + case 'FileContentViewerScreen.clearFileContent': return '确认清空文件内容?'; + case 'FileContentViewerScreen.clearFileContentTips': return '确认清空配置文件内容? 清空配置文件可能会导致数据丢失或应用功能异常, 请谨慎操作'; + case 'HomeScreen.toSelectServer': return '请选择服务器'; + case 'HomeScreen.invalidServer': return '已失效,请重新选择'; + case 'HomeScreen.disabledServer': return '已被禁用,请重新选择'; + case 'HomeScreen.expiredServer': return '无可用服务器:配置可能已过期或被禁用'; + case 'HomeScreen.systemProxyTips': return ({required Object sp, required Object hp}) => 'socks:${sp},http(s):${hp}'; + case 'HomeScreen.trafficTotal': return '总流量'; + case 'HomeScreen.trafficProxy': return '代理流量'; + case 'HomeScreen.myLinkEmpty': return '请先设置[快捷链接]后再使用'; + case 'HomeScreen.deviceNoSpace': return '磁盘空间不足'; + case 'HomeScreen.tooMuchServers': return ({required Object p, required Object p1}) => '代理服务器[${p}>${p1}]过多,可能因系统内存限制而无法连接'; + case 'LaunchFailedScreen.invalidProcess': return '应用启动失败[无效的进程名称],请重新安装应用到独立目录'; + case 'LaunchFailedScreen.invalidProfile': return '应用启动失败[访问配置文件失败],请重新安装应用'; + case 'LaunchFailedScreen.invalidVersion': return '应用启动失败[无效版本],请重新安装应用'; + case 'LaunchFailedScreen.systemVersionLow': return '应用启动失败[系统版本过低]'; + case 'LaunchFailedScreen.invalidInstallPath': return '无效的安装路径,请重新安装到有效路径'; + case 'MyProfilesEditScreen.title': return '编辑配置'; + case 'MyProfilesEditScreen.urlExist': return 'URL已存在,请使用其他URL'; + case 'MyProfilesEditScreen.updateTimerInterval': return '更新时间间隔'; + case 'MyProfilesEditScreen.updateTimerIntervalTips': return '最小:5m'; + case 'MyProfilesEditScreen.reloadAfterProfileUpdate': return '配置更新后重新加载'; + case 'MyProfilesEditScreen.testLatencyAfterProfileUpdate': return '配置自动更新后启动延迟测试'; + case 'MyProfilesEditScreen.testLatencyAfterProfileUpdateTips': return 'VPN需要处于已连接状态,并且开启[配置更新后重新加载]'; + case 'MyProfilesEditScreen.testLatencyAutoRemove': return '自动移除延迟测试失败的服务器'; + case 'MyProfilesEditScreen.testLatencyAutoRemoveTips': return '最多尝试3次'; + case 'MyProfilesMergeScreen.profilesMerge': return '配置合并'; + case 'MyProfilesMergeScreen.profilesMergeTarget': return '目标配置'; + case 'MyProfilesMergeScreen.profilesMergeSource': return '源配置'; + case 'MyProfilesMergeScreen.profilesMergeTips': return '提示:源配置的分流信息将会被丢弃'; + case 'MyProfilesScreen.title': return '我的配置'; + case 'MyProfilesScreen.atLeastOneEnable': return '无法禁用,请至少保留一个配置可用'; + case 'NetCheckScreen.title': return '网络检测'; + case 'NetCheckScreen.warn': return '注意:由于受网络环境及分流规则等影响,测试结果并不完全等价实际中使用的效果'; + case 'NetCheckScreen.check': return '检测'; + case 'NetCheckScreen.invalidDomain': return '无效域名'; + case 'NetCheckScreen.connectivity': return '网络联通性'; + case 'NetCheckScreen.connectivityTestIpv4AllFailed': return ({required Object p}) => 'Ipv4 连接测试[${p}]全部失败'; + case 'NetCheckScreen.connectivityTestIpv4Ok': return 'Ipv4 连接成功'; + case 'NetCheckScreen.connectivityTestIpv6AllFailed': return ({required Object p}) => 'Ipv6 连接测试[${p}]全部失败, 你的网络可能不支持ipv6'; + case 'NetCheckScreen.connectivityTestIpv6Ok': return 'Ipv6 连接成功'; + case 'NetCheckScreen.connectivityTestOk': return '网络已接入互联网'; + case 'NetCheckScreen.connectivityTestFailed': return '网络尚未接入互联网'; + case 'NetCheckScreen.remoteRulesetsDownloadOk': return '全部下载成功'; + case 'NetCheckScreen.remoteRulesetsDownloadNotOk': return '正在下载或下载失败'; + case 'NetCheckScreen.outbound': return '代理服务器'; + case 'NetCheckScreen.outboundOk': return ({required Object p}) => '[${p}]连接成功'; + case 'NetCheckScreen.outboundFailed': return ({required Object p1, required Object p2}) => '[${p1}]连接失败\n错误:[${p2}]'; + case 'NetCheckScreen.dnsServer': return 'DNS服务器'; + case 'NetCheckScreen.dnsOk': return ({required Object p1, required Object p2, required Object p3, required Object p4}) => '[${p1}]域名解析成功\nDNS规则:[${p2}]\n延迟:[${p3} ms]\n地址:[${p4}]'; + case 'NetCheckScreen.dnsFailed': return ({required Object p1, required Object p2, required Object p3}) => '[${p1}]域名解析失败\n规则:[${p2}]\n错误:[${p3}]'; + case 'NetCheckScreen.host': return 'HTTP连接'; + case 'NetCheckScreen.hostConnection': return ({required Object p1, required Object p2, required Object p3}) => '[${p1}]\n分流规则:[${p2}]\n代理服务器:[${p3}]'; + case 'NetCheckScreen.hostConnectionOk': return '连接成功'; + case 'NetCheckScreen.hostConnectionFailed': return ({required Object p}) => '连接失败:[${p}]'; + case 'NetConnectionsFilterScreen.title': return '连接状态筛选'; + case 'NetConnectionsFilterScreen.hostIp': return '域名/IP'; + case 'NetConnectionsFilterScreen.app': return '应用'; + case 'NetConnectionsFilterScreen.rule': return '规则'; + case 'NetConnectionsFilterScreen.chain': return '出站'; + case 'NetConnectionsScreen.title': return '连接状态'; + case 'NetConnectionsScreen.copyAsCSV': return '已复制为CSV格式'; + case 'NetConnectionsScreen.selectType': return '选择分流类型'; + case 'PerAppAndroidScreen.title': return '分应用代理'; + case 'PerAppAndroidScreen.whiteListMode': return '白名单模式'; + case 'PerAppAndroidScreen.whiteListModeTip': return '启用后:仅代理已勾选的App;未启用:仅代理未勾选的App'; + case 'PerAppAndroidScreen.hideSystemApp': return '隐藏系统应用'; + case 'PerAppAndroidScreen.hideAppIcon': return '隐藏应用图标'; + case 'PerAppAndroidScreen.enableAppQueryPermission': return '开启 [获取应用列表] 权限'; + case 'QrcodeScreen.tooLong': return '文本过长,无法展示'; + case 'QrcodeScreen.copy': return '拷贝链接'; + case 'QrcodeScreen.open': return '打开链接'; + case 'QrcodeScreen.share': return '分享链接'; + case 'QrcodeScreen.shareImage': return '分享二维码'; + case 'RegionSettingsScreen.title': return '国家与地区'; + case 'RegionSettingsScreen.Regions': return '提示:请正确设置你当前所在国家或地区,否则可能会导致分流错误'; + case 'ServerSelectScreen.title': return '选择服务器'; + case 'ServerSelectScreen.autoSelectServer': return '自动选择延迟最低的服务器'; + case 'ServerSelectScreen.recentUse': return '最近使用'; + case 'ServerSelectScreen.myFav': return '我的收藏'; + case 'ServerSelectScreen.selectLocal': return ({required Object p}) => '所选服务器为本地地址,可能无法正常使用:${p}'; + case 'ServerSelectScreen.selectRequireEnableIPv6': return '所选服务器为IPv6地址,需要[启用IPv6]'; + case 'ServerSelectScreen.selectDisabled': return '该服务器已被禁用'; + case 'ServerSelectScreen.error404': return '延迟检测遇到错误,请检查是否存在内容相同的配置'; + case 'SettingsScreen.ispFaq': return ({required Object p}) => 'FAQ[${p}]'; + case 'SettingsScreen.cleanISP': return ({required Object p}) => '清除ISP[${p}]'; + case 'SettingsScreen.openISP': return '打开ISP链接'; + case 'SettingsScreen.cleanISPNoParam': return '清除ISP信息'; + case 'SettingsScreen.getTranffic': return '获取流量'; + case 'SettingsScreen.tutorial': return '使用教程'; + case 'SettingsScreen.commonlyUsedRulesets': return '常用规则集'; + case 'SettingsScreen.howToRemoveAds': return '如何移除广告'; + case 'SettingsScreen.htmlBoard': return '在线面板'; + case 'SettingsScreen.dnsLeakDetection': return 'DNS泄露检测'; + case 'SettingsScreen.speedTest': return '测速'; + case 'SettingsScreen.downloadProfilePreferProxy': return '优先使用代理下载配置'; + case 'SettingsScreen.downloadProfilePreferProxyTips': return '如果当前已连接,则优先通过已连接的代理下载配置'; + case 'SettingsScreen.rulesetDirectDownlad': return 'Rule Set直连下载'; + case 'SettingsScreen.hideUnusedDiversionGroup': return '隐藏未启用的分流组'; + case 'SettingsScreen.disableISPDiversionGroup': return '禁用ISP分流规则'; + case 'SettingsScreen.portSetting': return '端口'; + case 'SettingsScreen.portSettingRule': return '基于规则'; + case 'SettingsScreen.portSettingDirectAll': return '全直连'; + case 'SettingsScreen.portSettingProxyAll': return '全代理'; + case 'SettingsScreen.portSettingControl': return '控制与同步'; + case 'SettingsScreen.portSettingCluster': return '集群服务'; + case 'SettingsScreen.modifyPort': return '修改端口'; + case 'SettingsScreen.modifyPortOccupied': return '端口已被占用,请使用其他端口'; + case 'SettingsScreen.ipStrategyTips': return '启用前,请先确认你的网络已支持IPv6,否则某些流量无法正常访问'; + case 'SettingsScreen.tunAppendHttpProxy': return '附加HTTP代理到VPN'; + case 'SettingsScreen.tunAppendHttpProxyTips': return '一些App会绕过虚拟网卡设备直连HTTP代理'; + case 'SettingsScreen.tlsInsecureEnable': return '跳过证书验证'; + case 'SettingsScreen.tlsFragmentEnable': return '启用TLS分段'; + case 'SettingsScreen.tlsFragmentSize': return 'TLS分段大小'; + case 'SettingsScreen.tlsFragmentSleep': return 'TLS分段休眠'; + case 'SettingsScreen.tlsMixedCaseSNIEnable': return '启用TLS混合SNI'; + case 'SettingsScreen.tlsPaddingEnable': return '启用TLS填充'; + case 'SettingsScreen.tlsPaddingSize': return 'TLS填充大小'; + case 'SettingsScreen.dnsEnableRule': return '启用DNS分流规则'; + case 'SettingsScreen.dnsEnableFakeIp': return '启用FakeIP'; + case 'SettingsScreen.dnsEnableClientSubnet': return '启用ECS'; + case 'SettingsScreen.dnsEnableProxyResolveByProxy': return '[代理流量]通过代理服务器解析DNS'; + case 'SettingsScreen.dnsEnableFinalResolveByProxy': return '[final]通过代理服务器解析DNS'; + case 'SettingsScreen.dnsTestDomain': return '测试域名'; + case 'SettingsScreen.dnsTestDomainInvalid': return '无效的域名'; + case 'SettingsScreen.dnsTypeOutbound': return '代理服务器'; + case 'SettingsScreen.dnsTypeDirect': return '直连流量'; + case 'SettingsScreen.dnsTypeProxy': return '代理流量'; + case 'SettingsScreen.dnsTypeResolver': return 'DNS服务器'; + case 'SettingsScreen.dnsEnableRuleTips': return '启用后,域名会根据分流规则选择对应的DNS服务器进行解析'; + case 'SettingsScreen.dnsEnableFakeIpTips': return '启用FakeIP后,如果断开VPN连接,你的应用可能需要重启;此功能需要开启[TUN模式]'; + case 'SettingsScreen.dnsTypeOutboundTips': return '用于代理服务器的域名解析'; + case 'SettingsScreen.dnsTypeDirectTips': return '用于直连流量的域名解析'; + case 'SettingsScreen.dnsTypeProxyTips': return '用于代理流量的域名解析'; + case 'SettingsScreen.dnsTypeResolverTips': return '用于DNS服务器的域名解析'; + case 'SettingsScreen.dnsTypeFinalTips': return '用于其他流量的域名解析'; + case 'SettingsScreen.dnsAutoSetServer': return '自动设置服务器'; + case 'SettingsScreen.dnsResetServer': return '重置服务器'; + case 'SettingsScreen.inboundDomainResolve': return '解析入站域名'; + case 'SettingsScreen.privateDirect': return '私有网络直连'; + case 'SettingsScreen.inboundDomainResolveTips': return ({required Object p}) => '某些未配置分流规则的域名需要解析后才可能命中基于IP的分流规则;此功能影响代理端口[${p}]的入站请求'; + case 'SettingsScreen.useRomoteRes': return '使用远程资源'; + case 'SettingsScreen.autoSelect': return '自动选择'; + case 'SettingsScreen.autoSelectServerIgnorePerProxyServer': return '忽略[前置代理]代理服务器'; + case 'SettingsScreen.autoSelectServerInterval': return '延迟检测时间间隔'; + case 'SettingsScreen.autoSelectServerReTestIfNetworkUpdate': return '网络变化时重新检测'; + case 'SettingsScreen.autoSelectServerUpdateCurrentServerAfterManualUrltest': return '手动延时检测后更新当前服务器'; + case 'SettingsScreen.autoSelectServerIntervalTips': return '延迟检测时间间隔越短,服务器延迟数据更新越及时,但会占用更多资源,耗电更快'; + case 'SettingsScreen.autoSelectServerFavFirst': return '优先使用[我的收藏]'; + case 'SettingsScreen.autoSelectServerFavFirstTips': return '如果[我的收藏]列表不为空,则使用[我的收藏]里的服务器'; + case 'SettingsScreen.autoSelectServerFilter': return '过滤无效服务器'; + case 'SettingsScreen.autoSelectServerFilterTips': return ({required Object p}) => '服务器延迟检测失败的将会被过滤掉;如果过滤后无服务器可用,则改用前[${p}]个服务器'; + case 'SettingsScreen.autoSelectServerLimitedNum': return '服务器数量上限'; + case 'SettingsScreen.autoSelectServerLimitedNumTips': return '超过该数量的服务器将被过滤掉'; + case 'SettingsScreen.numInvalid': return '无效的数字'; + case 'SettingsScreen.hideInvalidServer': return '隐藏无效服务器'; + case 'SettingsScreen.sortServer': return '服务器排序'; + case 'SettingsScreen.sortServerTips': return '按延迟由低到高排序'; + case 'SettingsScreen.selectServerHideRecommand': return '隐藏[推荐]'; + case 'SettingsScreen.selectServerHideRecent': return '隐藏[最近使用]'; + case 'SettingsScreen.selectServerHideFav': return '隐藏[我的收藏]'; + case 'SettingsScreen.homeScreen': return '主屏'; + case 'SettingsScreen.theme': return '主题'; + case 'SettingsScreen.myLink': return '快捷链接'; + case 'SettingsScreen.myLinkInvalid': return '无效的URL'; + case 'SettingsScreen.autoConnectAfterLaunch': return '启动后自动连接'; + case 'SettingsScreen.hideAfterLaunch': return '启动后隐藏窗口'; + case 'SettingsScreen.autoSetSystemProxy': return '连接后自动设置系统代理'; + case 'SettingsScreen.disconnectWhenQuit': return '退出应用时关闭连接'; + case 'SettingsScreen.allowBypass': return '允许应用绕过VPN'; + case 'SettingsScreen.importSuccess': return '导入成功'; + case 'SettingsScreen.rewriteConfirm': return '该文件将覆盖本地已有配置,是否继续?'; + case 'SettingsScreen.networkShare': return '网络共享'; + case 'SettingsScreen.frontProxy': return '前置代理'; + case 'SettingsScreen.frontProxyTips': return ({required Object p}) => '数据->前置代理服务器[多个前置代理服务器:由上到下]->代理服务器[${p}]->目标服务器'; + case 'SettingsScreen.allowOtherHostsConnect': return '允许其他主机接入'; + case 'SettingsScreen.allowOtherHostsConnectTips': return ({required Object sp, required Object hp}) => 'socks:${sp},http(s):${hp}'; + case 'SettingsScreen.tunAutoRoute': return 'Auto Route'; + case 'SettingsScreen.tunStrictRoute': return '严格路由'; + case 'SettingsScreen.tunStrictRouteTips': return '如果开启共享后,其他无法接入此设备,请尝试关闭此开关'; + case 'SettingsScreen.enableCluster': return '开启Socks/Http代理集群'; + case 'SettingsScreen.clusterAllowOtherHostsConnect': return '允许其他主机接入代理集群'; + case 'SettingsScreen.clusterAllowOtherHostsConnectTips': return ({required Object ip, required Object port}) => 'http://${ip}:${port}/get_proxies'; + case 'SettingsScreen.clusterAuth': return '代理集群认证'; + case 'SettingsScreen.tunMode': return 'TUN模式'; + case 'SettingsScreen.tunModeTips': return 'TUN模式将接管系统所有流量[此模式下无需开启系统代理]'; + case 'SettingsScreen.tunModeRunAsAdmin': return 'TUN模式需要系统管理员权限,请以管理员身份重新启动应用'; + case 'SettingsScreen.tunStack': return '网络栈'; + case 'SettingsScreen.launchAtStartup': return '开机启动'; + case 'SettingsScreen.quitWhenSwitchSystemUser': return '切换系统用户时退出应用'; + case 'SettingsScreen.handleScheme': return '系统Scheme调用'; + case 'SettingsScreen.portableMode': return '便携模式'; + case 'SettingsScreen.portableModeDisableTips': return '如需退出便携模式,请退出[karing]后,手动删除[karing.exe]同目录下的[profiles]文件夹即可'; + case 'SettingsScreen.handleKaringScheme': return '处理karing://调用'; + case 'SettingsScreen.handleClashScheme': return '处理clash://调用'; + case 'SettingsScreen.handleSingboxScheme': return '处理sing-box://调用'; + case 'SettingsScreen.alwayOnVPN': return '始终开启连接'; + case 'SettingsScreen.removeSystemVPNConfig': return '删除系统VPN配置'; + case 'SettingsScreen.timeConnectOrDisconnect': return '定时连接/断开'; + case 'SettingsScreen.timeConnectOrDisconnectTips': return 'VPN必须处于连接状态才会生效;开启后,[自动休眠]将失效'; + case 'SettingsScreen.timeConnectAndDisconnectInterval': return ({required Object p}) => '连接/断开时间间隔不能低于${p}分钟'; + case 'SettingsScreen.disableFontScaler': return '禁用字体缩放'; + case 'SettingsScreen.autoOrientation': return '跟随屏幕旋转'; + case 'SettingsScreen.restartTakesEffect': return '重启生效'; + case 'SettingsScreen.resetSettings': return '重置设置'; + case 'SettingsScreen.cleanCache': return '清理缓存'; + case 'SettingsScreen.cleanCacheDone': return '清理完成'; + case 'SettingsScreen.appleTestFlight': return '苹果 TestFlight'; + case 'SettingsScreen.appleAppStore': return '苹果 AppStore'; + case 'SettingsScreen.hasNewVersion': return ({required Object p}) => '更新版本 ${p}'; + case 'SettingsScreen.follow': return '关注我们'; + case 'SettingsScreen.contactUs': return '联系我们'; + case 'SettingsScreen.rateInApp': return '评分'; + case 'SettingsScreen.rateInAppStore': return '在App Store上评分'; + case 'SpeedTestSettingsScreen.title': return '测速URL'; + case 'TextToQrCodeScreen.title': return '文本转二维码'; + case 'TextToQrCodeScreen.convert': return '转换'; + case 'UserAgreementScreen.privacyFirst': return '您的隐私很重要'; + case 'UserAgreementScreen.agreeAndContinue': return '接受并继续'; + case 'VersionUpdateScreen.versionReady': return ({required Object p}) => '新版本[${p}]已就绪'; + case 'VersionUpdateScreen.update': return '重启更新'; + case 'VersionUpdateScreen.cancel': return '暂不更新'; + case 'CommonWidget.diableAlwayOnVPN': return '如果开启了[始终开启VPN], 请关闭[始终开启VPN]后重试连接'; + case 'CommonWidget.resetPort': return '请将端口改为其他可用端口或者关闭占用该端口的应用'; + case 'ServerManager.noServerAvaliable': return '无可用服务器,请确保配置链接或配置文件有效;如果你的配置来源于GitHub,请从页面上的[Raw]按钮获取链接地址'; + case 'ServerManager.filePathCannotEmpty': return '文件路径不能为空'; + case 'ServerManager.fileNotExist': return ({required Object p}) => '文件不存在:${p}'; + case 'ServerManager.urlCannotEmpty': return '链接不能为空'; + case 'ServerManager.invalidUrl': return '错误的配置链接'; + case 'ServerManager.parseFailed': return '解析配置失败'; + case 'main.tray.menuOpen': return ' 打开 '; + case 'main.tray.menuExit': return ' 退出 '; + case 'enable': return '启用'; + case 'disable': return '禁用'; + case 'filter': return '过滤'; + case 'filterMethod': return '过滤方式'; + case 'include': return '包含'; + case 'exclude': return '排除'; + case 'all': return '所有'; + case 'prefer': return '优先'; + case 'only': return '仅'; + case 'open': return '打开'; + case 'close': return '关闭'; + case 'quit': return '退出'; + case 'add': return '添加'; + case 'remove': return '删除'; + case 'edit': return '编辑'; + case 'view': return '查看'; + case 'more': return '更多'; + case 'addProfile': return '添加配置'; + case 'addSuccess': return '添加成功'; + case 'addSuccessThen': return ({required Object p}) => '配置生成成功,请到[${p}]查看'; + case 'addFailed': return ({required Object p}) => '添加失败:${p}'; + case 'removeConfirm': return '确认删除?'; + case 'tips': return '提示'; + case 'copy': return '拷贝'; + case 'ok': return '确定'; + case 'cancel': return '取消'; + case 'feedback': return '反馈'; + case 'faq': return '常见问题'; + case 'download': return '下载'; + case 'loading': return '加载中...'; + case 'updateFailed': return ({required Object p}) => '更新失败:${p}'; + case 'days': return '天'; + case 'hours': return '时'; + case 'minutes': return '分'; + case 'seconds': return '秒'; + case 'protocol': return '协议'; + case 'search': return '搜索'; + case 'custom': return '自定义'; + case 'connect': return '连接'; + case 'disconnect': return '断开'; + case 'connected': return '已连接'; + case 'disconnected': return '未连接'; + case 'connecting': return '连接中'; + case 'connectTimeout': return '连接超时'; + case 'timeout': return '超时'; + case 'language': return '语言'; + case 'next': return '下一步'; + case 'done': return '完成'; + case 'apply': return '应用'; + case 'refresh': return '刷新'; + case 'retry': return '是否重试?'; + case 'none': return '无'; + case 'reset': return '重置'; + case 'submit': return '提交'; + case 'account': return '账号'; + case 'password': return '密码'; + case 'required': return '必填'; + case 'diversion': return '分流'; + case 'diversionRules': return '分流规则'; + case 'diversionRulesEnable': return '启用[ISP]分流规则'; + case 'diversionCustomGroup': return '自定义分流组'; + case 'diversionCustomGroupPreset': return '预置[自定义分流组]'; + case 'diversionCustomGroupPresetTips': return '注意:启用的项会添加/覆盖到[自定义分流组]和[分流规则]'; + case 'diversionCustomGroupAddTips': return '注意:添加完毕后可能需要手动调整排序,否则新添加的分流可能不会生效'; + case 'urlTestCustomGroup': return '自定义代理组'; + case 'rulesetEnableTips': return '提示:开启选项后,请到[分流规则]设置相关规则,否则不会生效'; + case 'ispUserAgentTips': return '[ISP]会根据[HTTP]请求里的[UserAgent]下发不同订阅类型的数据'; + case 'ispDiversionTips': return '[ISP]提供的分流规则;[V2Ray]类型的订阅不支持分流规则'; + case 'staticIP': return '静态IP'; + case 'other': return '其他'; + case 'dns': return 'DNS'; + case 'url': return 'URL'; + case 'isp': return 'ISP'; + case 'tls': return 'TLS'; + case 'userAgent': return 'UserAgent'; + case 'urlInvalid': return '无效URL'; + case 'outboundActionCurrentSelected': return '当前选择'; + case 'outboundActionUrltest': return '自动选择'; + case 'outboundActionDirect': return '直连'; + case 'outboundActionBlock': return '拦截'; + case 'routeFinal': return 'final'; + case 'rulesetGeoSite': return 'GeoSite'; + case 'rulesetGeoIp': return 'GeoIP'; + case 'rulesetAcl': return 'ACL'; + case 'iCloud': return 'iCloud'; + case 'appleTV': return 'Apple TV'; + case 'webdav': return 'Webdav'; + case 'setting': return '设置'; + case 'protocolSniff': return '协议探测'; + case 'protocolSniffOverrideDestination': return '探测的域名覆盖连接目标地址'; + case 'remark': return '备注'; + case 'remarkCannotEmpty': return '备注不能为空'; + case 'remarkTooLong': return '备注最长32字符'; + case 'remarkExist': return '备注已存在,请使用其他名称'; + case 'domainSuffix': return '域名后缀'; + case 'domain': return '域名'; + case 'domainKeyword': return '域名关键词'; + case 'domainRegex': return '域名正则'; + case 'ip': return 'IP'; + case 'port': return '端口'; + case 'appPackage': return '应用包名'; + case 'processName': return '进程名称'; + case 'processPath': return '进程路径'; + case 'systemProxy': return '系统代理'; + case 'netInterfaces': return '网络接口'; + case 'netSpeed': return '速度'; + case 'website': return '官网'; + case 'rule': return '规则'; + case 'global': return '全局'; + case 'qrcode': return '二维码'; + case 'scanQrcode': return '扫描二维码'; + case 'scanResult': return '扫描结果'; + case 'backupAndSync': return '备份与同步'; + case 'importAndExport': return '导入/导出'; + case 'import': return '导入'; + case 'export': return '导出'; + case 'send': return '发送'; + case 'receive': return '接收'; + case 'sendOrReceiveNotMatch': return ({required Object p}) => '请使用[${p}]'; + case 'sendConfirm': return '确认发送?'; + case 'termOfUse': return '使用条款'; + case 'privacyPolicy': return '隐私政策'; + case 'about': return '关于'; + case 'name': return '名称'; + case 'version': return '版本'; + case 'notice': return '通知'; + case 'sort': return '排序'; + case 'novice': return '新手模式'; + case 'recommended': return '推荐'; + case 'innerError': return ({required Object p}) => '内部错误:${p}'; + case 'logicOperation': return '逻辑运算'; + case 'share': return '分享'; + case 'candidateWord': return '候选词'; + case 'keywordOrRegx': return '关键词/正则'; + case 'importFromClipboard': return '从剪贴板导入'; + case 'exportToClipboard': return '导出到剪贴板'; + case 'server': return '服务器'; + case 'appleTVConnectTurnOfprivateDirect': return '请先开启[私有网络直连]'; + case 'targetConnectFailed': return ({required Object p}) => '连接[${p}]失败,请确保设备在同一个局域网内,并且开启[私有网络直连]'; + case 'appleTVSync': return '同步当前核心配置到Apple TV - Karing'; + case 'appleTVSyncDone': return '同步完成,请到Apple TV - Karing开启连接/重启连接'; + case 'appleTVRemoveCoreConfig': return '删除Apple TV - Karing核心配置'; + case 'appleTVRemoveCoreConfigDone': return 'Apple TV - Karing的核心配置文件已删除;VPN服务已断开连接'; + case 'appleTVUrlInvalid': return '无效的URL,请打开Apple TV - Karing,扫描Karing显示的二维码'; + case 'remoteProfileEditConfirm': return '配置更新后,节点的修改将会被还原,是否继续?'; + case 'invalidFileType': return ({required Object p}) => '无效的文件类型:${p}'; + case 'mustBeValidHttpsURL': return '必须为有效的 https URL'; + case 'fileNotExistReinstall': return ({required Object p}) => '文件缺失[${p}],请重新安装'; + case 'latencyTest': return '延迟检测'; + case 'latencyTestResolveIP': return '手动检测时,同时解析出口IP'; + case 'uwpExemption': return 'UWP网络隔离豁免'; + case 'removeBannerAds': return '去除广告'; + case 'removeBannerAdsByReward': return '观看一段数秒广告,将会获得7天无广告奖励'; + case 'removeBannerAdsByRewardDone': return '已获得7天无广告奖励'; + case 'locales.en': return 'English'; + case 'locales.zh-CN': return '简体中文'; + case 'locales.ar': return 'عربي'; + case 'locales.ru': return 'Русский'; + case 'locales.fa': return 'فارسی'; + default: return null; + } + } +} + diff --git a/lib/main.dart b/lib/main.dart index 551b338..a662803 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,16 +1,15 @@ // ignore_for_file: empty_catches, unused_catch_stack import 'dart:async'; -import 'dart:convert'; import 'dart:io'; -import 'dart:math'; import 'dart:ui'; - +import 'package:karing/app/private/ads_private.dart'; +import 'package:karing/app/utils/did.dart'; +import 'package:path_provider/path_provider.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_inapp_notifications/flutter_inapp_notifications.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; -import 'package:karing/app/local_services/vpn_service.dart'; import 'package:karing/app/modules/app_lifecycle_state_notify_manager.dart'; import 'package:karing/app/modules/biz.dart'; import 'package:karing/app/modules/remote_config_manager.dart'; @@ -22,7 +21,7 @@ import 'package:karing/app/utils/app_args.dart'; import 'package:karing/app/utils/app_utils.dart'; import 'package:karing/app/utils/geoip_subnet_utils.dart'; import 'package:karing/app/utils/file_utils.dart'; -import 'package:karing/app/utils/google_admob.dart'; + import 'package:karing/app/utils/log.dart'; import 'package:karing/app/utils/path_utils.dart'; import 'package:karing/app/utils/platform_utils.dart'; @@ -49,6 +48,13 @@ StartFailedReason? startFailedReason; String? startFailedReasonDesc; void main(List args) async { + /* String dir = "E:\\dev\\KaringX\\karing-ruleset\\geo\\geoip"; + String target = path.join(dir, "geoip_subnets.json"); + var files = FileUtils.recursionFile(dir, filter: {".json"}); + var subnets = await GeoipSubnetUtils.genClientSubnet(files); + await GeoipSubnetUtils.saveSubnets(subnets, target); + return;*/ + processArgs = args; WidgetsFlutterBinding.ensureInitialized(); await RemoteConfigManager.init(); @@ -76,8 +82,11 @@ Future run(List args) async { startFailedReason = StartFailedReason.invalidProfile; } if (Platform.isWindows) { - if (exePath.contains("UNC/") || exePath.contains("UNC\\")) { - startFailedReason = StartFailedReason.startFromUNC; + var tmp = await getTemporaryDirectory(); + if (exePath.contains("UNC/") || + exePath.contains("UNC\\") || + exePath.startsWith(tmp.absolute.path.toUpperCase())) { + startFailedReason = StartFailedReason.invalidInstallPath; } if (path.basename(exePath).toLowerCase() != AppUtils.getKaringExe()) { startFailedReason = StartFailedReason.invalidProcess; @@ -141,6 +150,8 @@ Future run(List args) async { } } } + bool first = await Did.getFirstTime(); + AdsPrivate.init(first); runApp(TranslationProvider( child: const MyApp(), @@ -396,8 +407,6 @@ class MyAppState extends State }); await Biz.init(_launchAtStartup); - VPNService.onServiceNotify( - (String cmd, Map params) async {}); } else { firstShowWindow(true); } diff --git a/lib/screens/about_screen.dart b/lib/screens/about_screen.dart index 58947a9..9270d3b 100644 --- a/lib/screens/about_screen.dart +++ b/lib/screens/about_screen.dart @@ -53,6 +53,7 @@ class AboutScreenState extends LasyRenderingState { @override Widget build(BuildContext context) { final tcontext = Translations.of(context); + Size windowSize = MediaQuery.of(context).size; return Scaffold( appBar: PreferredSize( preferredSize: Size.zero, @@ -79,11 +80,16 @@ class AboutScreenState extends LasyRenderingState { ), ), ), - Text( - tcontext.about, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2, + child: Text( + tcontext.about, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), const SizedBox( width: 50, @@ -391,7 +397,8 @@ class AboutScreenState extends LasyRenderingState { return; } DialogUtils.showAlertDialog( - context, cresult.error!.message.toString()); + context, cresult.error!.message.toString(), + showCopy: true, showFAQ: true, withVersion: true); return; } SettingManager.getConfig().originSBProfile = filePath; @@ -402,7 +409,8 @@ class AboutScreenState extends LasyRenderingState { if (!mounted) { return; } - DialogUtils.showAlertDialog(context, err.toString()); + DialogUtils.showAlertDialog(context, err.toString(), + showCopy: true, showFAQ: true, withVersion: true); } } } diff --git a/lib/screens/add_profile_by_import_from_file_screen.dart b/lib/screens/add_profile_by_import_from_file_screen.dart index 493df64..1f6cafa 100644 --- a/lib/screens/add_profile_by_import_from_file_screen.dart +++ b/lib/screens/add_profile_by_import_from_file_screen.dart @@ -7,8 +7,10 @@ import 'package:flutter/material.dart'; import 'package:karing/app/modules/server_manager.dart'; import 'package:karing/app/runtime/return_result.dart'; import 'package:karing/app/utils/auto_conf_utils.dart'; +import 'package:karing/app/utils/proxy_conf_utils.dart'; import 'package:karing/i18n/strings.g.dart'; import 'package:karing/screens/dialog_utils.dart'; +import 'package:karing/screens/group_helper.dart'; import 'package:karing/screens/group_item.dart'; import 'package:karing/screens/theme_config.dart'; import 'package:karing/screens/widgets/framework.dart'; @@ -36,6 +38,7 @@ class _AddProfileByImportFromFileScreenState final _textControllerRemark = TextEditingController(); bool _loading = false; bool _enableDiversionRules = false; + ProxyFilter _proxyFilter = ProxyFilter(); @override void initState() { super.initState(); @@ -72,7 +75,7 @@ class _AddProfileByImportFromFileScreenState setState(() {}); ReturnResultError? error = await ServerManager.addLocalConfig( - text, _filePath, widget.type, _enableDiversionRules); + text, _filePath, widget.type, _proxyFilter, _enableDiversionRules); if (!mounted) { return; @@ -89,7 +92,7 @@ class _AddProfileByImportFromFileScreenState }); } else { DialogUtils.showAlertDialog(context, tcontext.addFailed(p: error.message), - showCopy: true, withVersion: true) + showCopy: true, showFAQ: true, withVersion: true) .then((value) {}); } } @@ -97,6 +100,7 @@ class _AddProfileByImportFromFileScreenState @override Widget build(BuildContext context) { final tcontext = Translations.of(context); + Size windowSize = MediaQuery.of(context).size; return Scaffold( appBar: PreferredSize( preferredSize: Size.zero, @@ -121,13 +125,18 @@ class _AddProfileByImportFromFileScreenState ), ), ), - Text( - widget.title.isNotEmpty - ? widget.title - : tcontext.AddProfileByImportFromFileScreen.title, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2, + child: Text( + widget.title.isNotEmpty + ? widget.title + : tcontext.AddProfileByImportFromFileScreen.title, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), _loading ? const Row( @@ -270,7 +279,8 @@ class _AddProfileByImportFromFileScreenState if (!mounted) { return; } - DialogUtils.showAlertDialog(context, err.toString()); + DialogUtils.showAlertDialog(context, err.toString(), + showCopy: true, showFAQ: true, withVersion: true); } } @@ -278,6 +288,12 @@ class _AddProfileByImportFromFileScreenState final tcontext = Translations.of(context); List groupOptions = []; List options = [ + GroupItemOptions( + pushOptions: GroupItemPushOptions( + name: tcontext.filter, + onPush: () async { + onTapFilter(); + })), GroupItemOptions( switchOptions: GroupItemSwitchOptions( name: tcontext.diversionRulesEnable, @@ -291,4 +307,9 @@ class _AddProfileByImportFromFileScreenState groupOptions.add(GroupItem(options: options)); return groupOptions; } + + void onTapFilter() async { + _proxyFilter = await GroupHelper.showProxyFilter(context, _proxyFilter); + setState(() {}); + } } diff --git a/lib/screens/add_profile_by_link_or_content_screen.dart b/lib/screens/add_profile_by_link_or_content_screen.dart index 24c7c86..92c5812 100644 --- a/lib/screens/add_profile_by_link_or_content_screen.dart +++ b/lib/screens/add_profile_by_link_or_content_screen.dart @@ -52,6 +52,7 @@ class _AddProfileByLinkOrContentScreenState bool _loading = false; bool _enableDiversionRules = false; String _compatible = ""; + ProxyFilter _proxyFilter = ProxyFilter(); Duration? _updateTimeInterval = const Duration(hours: 12); @override @@ -178,6 +179,7 @@ class _AddProfileByLinkOrContentScreenState url, SubscriptionLinkType.unknown, _compatible, + _proxyFilter, _enableDiversionRules, _updateTimeInterval, ispName: widget.ispName, @@ -217,12 +219,13 @@ class _AddProfileByLinkOrContentScreenState setState(() {}); DialogUtils.showAlertDialog(context, err, - showCopy: true, withVersion: true); + showCopy: true, showFAQ: true, withVersion: true); } @override Widget build(BuildContext context) { final tcontext = Translations.of(context); + Size windowSize = MediaQuery.of(context).size; return Scaffold( appBar: PreferredSize( preferredSize: Size.zero, @@ -247,11 +250,16 @@ class _AddProfileByLinkOrContentScreenState ), ), ), - Text( - tcontext.AddProfileByLinkOrContentScreen.title, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2, + child: Text( + tcontext.AddProfileByLinkOrContentScreen.title, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), _loading ? const Row( @@ -371,6 +379,12 @@ class _AddProfileByLinkOrContentScreenState onPush: () async { onTapUserAgent(); })), + GroupItemOptions( + pushOptions: GroupItemPushOptions( + name: tcontext.filter, + onPush: () async { + onTapFilter(); + })), GroupItemOptions( switchOptions: GroupItemSwitchOptions( name: tcontext.diversionRulesEnable, @@ -407,4 +421,9 @@ class _AddProfileByLinkOrContentScreenState _compatible = await GroupHelper.showUserAgent(context, _compatible); setState(() {}); } + + void onTapFilter() async { + _proxyFilter = await GroupHelper.showProxyFilter(context, _proxyFilter); + setState(() {}); + } } diff --git a/lib/screens/add_profile_by_scan_qrcode_screen.dart b/lib/screens/add_profile_by_scan_qrcode_screen.dart index 80bc656..8db8cd8 100644 --- a/lib/screens/add_profile_by_scan_qrcode_screen.dart +++ b/lib/screens/add_profile_by_scan_qrcode_screen.dart @@ -5,6 +5,7 @@ import 'dart:io'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import "package:images_picker/images_picker.dart"; +import 'package:path/path.dart' as path; import 'package:karing/app/utils/platform_utils.dart'; import 'package:karing/app/utils/qrcode_utils.dart'; import 'package:karing/i18n/strings.g.dart'; @@ -98,6 +99,7 @@ class _AddProfileByScanQrcodeScanScreenState List buildBar(BuildContext context) { final tcontext = Translations.of(context); + Size windowSize = MediaQuery.of(context).size; if (PlatformUtils.isMobile()) { return [ InkWell( @@ -111,11 +113,16 @@ class _AddProfileByScanQrcodeScanScreenState ), ), ), - Text( - tcontext.scanQrcode, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2 - (_scanFromFile ? 70 : 100), + child: Text( + tcontext.scanQrcode, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ _scanFromFile @@ -152,7 +159,8 @@ class _AddProfileByScanQrcodeScanScreenState try { await controller!.toggleFlash(); } catch (err) { - DialogUtils.showAlertDialog(context, err.toString()); + DialogUtils.showAlertDialog(context, err.toString(), + showCopy: true, showFAQ: true, withVersion: true); } setState(() {}); @@ -195,11 +203,16 @@ class _AddProfileByScanQrcodeScanScreenState ), ), ), - Text( - tcontext.scanQrcode, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2, + child: Text( + tcontext.scanQrcode, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), InkWell( onTap: () async { @@ -396,6 +409,13 @@ class _AddProfileByScanQrcodeScanScreenState } Future onPressScanFromImageMobile() async { + if (Platform.isAndroid) { + //ImagesPicker impl error on android + return await onPressScanFromImagePC(); + } + _image = null; + _qrContent = ""; + setState(() {}); final tcontext = Translations.of(context); List? result = await ImagesPicker.pick( count: 1, @@ -432,7 +452,10 @@ class _AddProfileByScanQrcodeScanScreenState DialogUtils.showAlertDialog( context, tcontext.AddProfileByScanQrcodeScanScreen.scanException( - p: err.toString())); + p: err.toString()), + showCopy: true, + showFAQ: true, + withVersion: true); } } } @@ -444,11 +467,21 @@ class _AddProfileByScanQrcodeScanScreenState setState(() {}); try { + List extensions = ['png', 'jpg']; FilePickerResult? result = await FilePicker.platform.pickFiles( - type: FileType.custom, - allowedExtensions: ['png', 'jpg'], + type: Platform.isAndroid ? FileType.any : FileType.custom, + allowedExtensions: Platform.isAndroid ? null : extensions, ); if (result != null) { + String ext = path + .extension(result.files.first.name) + .replaceAll('.', '') + .toLowerCase(); + if (!extensions.contains(ext)) { + DialogUtils.showAlertDialog( + context, tcontext.invalidFileType(p: ext)); + return; + } String filePath = result.files.first.path!; var file = File(filePath); if (await file.exists()) { @@ -473,7 +506,10 @@ class _AddProfileByScanQrcodeScanScreenState DialogUtils.showAlertDialog( context, tcontext.AddProfileByScanQrcodeScanScreen.scanException( - p: err.toString())); + p: err.toString()), + showCopy: true, + showFAQ: true, + withVersion: true); } } @@ -519,7 +555,10 @@ class _AddProfileByScanQrcodeScanScreenState DialogUtils.showAlertDialog( context, tcontext.AddProfileByScanQrcodeScanScreen.scanException( - p: err.toString())); + p: err.toString()), + showCopy: true, + showFAQ: true, + withVersion: true); } } } diff --git a/lib/screens/backup_and_sync_icloud_screen.dart b/lib/screens/backup_and_sync_icloud_screen.dart index daec0c9..a8febd2 100644 --- a/lib/screens/backup_and_sync_icloud_screen.dart +++ b/lib/screens/backup_and_sync_icloud_screen.dart @@ -5,6 +5,7 @@ import 'dart:async'; import 'package:after_layout/after_layout.dart'; import 'package:flutter/material.dart'; import 'package:karing/app/modules/server_manager.dart'; +import 'package:karing/app/runtime/return_result.dart'; import 'package:karing/app/utils/backup_and_sync_utils.dart'; import 'package:karing/app/utils/file_utils.dart'; import 'package:karing/app/utils/icloud_utils.dart'; @@ -54,6 +55,7 @@ class _BackupAndSyncIcloudScreenState @override Widget build(BuildContext context) { final tcontext = Translations.of(context); + Size windowSize = MediaQuery.of(context).size; return Scaffold( appBar: PreferredSize( preferredSize: Size.zero, @@ -80,11 +82,16 @@ class _BackupAndSyncIcloudScreenState ), ), ), - Text( - tcontext.iCloud, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2, + child: Text( + tcontext.iCloud, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), Row( children: [ @@ -255,7 +262,8 @@ class _BackupAndSyncIcloudScreenState setState(() {}); if (result.error != null) { - DialogUtils.showAlertDialog(context, result.error!.message); + DialogUtils.showAlertDialog(context, result.error!.message, + showCopy: true, showFAQ: true, withVersion: true); return; } _fileList = result.data!; @@ -270,13 +278,15 @@ class _BackupAndSyncIcloudScreenState try { String dir = await PathUtils.cacheDir(); String filePath = path.join(dir, BackupAndSyncUtils.getZipFileName()); - var error = await ServerManager.backupToZip(filePath); + ReturnResultError? error = await ServerManager.backupToZip(filePath); if (!mounted) { FileUtils.deleteFileByPath(filePath); return; } if (error != null) { - DialogUtils.showAlertDialog(context, error.message); + DialogUtils.showAlertDialog(context, error.message, + showCopy: true, showFAQ: true, withVersion: true); + return; } error = await ICloudUtils.upload( relativePath: path.basename(filePath), localPath: filePath); @@ -288,7 +298,8 @@ class _BackupAndSyncIcloudScreenState _uploading = false; setState(() {}); if (error != null) { - DialogUtils.showAlertDialog(context, error.message); + DialogUtils.showAlertDialog(context, error.message, + showCopy: true, showFAQ: true, withVersion: true); return; } await list(); @@ -298,7 +309,8 @@ class _BackupAndSyncIcloudScreenState } _uploading = false; setState(() {}); - DialogUtils.showAlertDialog(context, err.toString()); + DialogUtils.showAlertDialog(context, err.toString(), + showCopy: true, showFAQ: true, withVersion: true); } } @@ -311,13 +323,14 @@ class _BackupAndSyncIcloudScreenState } String dir = await PathUtils.cacheDir(); String filePath = path.join(dir, BackupAndSyncUtils.getZipFileName()); - var error = + ReturnResultError? error = await ICloudUtils.download(relativePath: filename, localPath: filePath); if (!mounted) { return; } if (error != null) { - DialogUtils.showAlertDialog(context, error.message); + DialogUtils.showAlertDialog(context, error.message, + showCopy: true, showFAQ: true, withVersion: true); return; } await GroupHelper.backupRestoreFromZip(context, filePath, confirm: false); @@ -330,7 +343,8 @@ class _BackupAndSyncIcloudScreenState return; } if (error != null) { - DialogUtils.showAlertDialog(context, error.message); + DialogUtils.showAlertDialog(context, error.message, + showCopy: true, showFAQ: true, withVersion: true); return; } await list(); diff --git a/lib/screens/backup_and_sync_lan_sync.dart b/lib/screens/backup_and_sync_lan_sync.dart index 5946d14..4ce4746 100644 --- a/lib/screens/backup_and_sync_lan_sync.dart +++ b/lib/screens/backup_and_sync_lan_sync.dart @@ -5,6 +5,7 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:karing/app/modules/server_manager.dart'; import 'package:karing/app/modules/setting_manager.dart'; +import 'package:karing/app/runtime/return_result.dart'; import 'package:karing/app/utils/app_scheme_utils.dart'; import 'package:karing/app/utils/app_utils.dart'; import 'package:karing/app/utils/backup_and_sync_utils.dart'; @@ -66,13 +67,13 @@ class _BackupAndSyncLanSyncScreenState if (widget.syncUpload != true) { String dir = await PathUtils.cacheDir(); _zipPath = path.join(dir, BackupAndSyncUtils.getZipFileName()); - var error = await ServerManager.backupToZip(_zipPath!); + ReturnResultError? error = await ServerManager.backupToZip(_zipPath!); if (error != null) { if (!mounted) { return; } - DialogUtils.showAlertDialog(context, error.toString(), - showCopy: true, withVersion: true); + DialogUtils.showAlertDialog(context, error.message, + showCopy: true, showFAQ: true, withVersion: true); return; } } @@ -124,7 +125,7 @@ class _BackupAndSyncLanSyncScreenState return; } DialogUtils.showAlertDialog(context, err.toString(), - showCopy: true, withVersion: true); + showCopy: true, showFAQ: true, withVersion: true); return; } @@ -233,8 +234,17 @@ class _BackupAndSyncLanSyncScreenState _sendNotFound(httpRequest.response); return; } - - result.item2.call(httpRequest); + try { + result.item2.call(httpRequest); + } catch (err) { + Future.delayed(const Duration(microseconds: 10), () async { + if (!mounted) { + return; + } + DialogUtils.showAlertDialog(context, err.toString(), + showCopy: true, showFAQ: true, withVersion: true); + }); + } } Future restoreFromZip(String zipPath) async { @@ -245,6 +255,7 @@ class _BackupAndSyncLanSyncScreenState @override Widget build(BuildContext context) { final tcontext = Translations.of(context); + Size windowSize = MediaQuery.of(context).size; return Scaffold( appBar: PreferredSize( preferredSize: Size.zero, @@ -271,11 +282,16 @@ class _BackupAndSyncLanSyncScreenState ), ), ), - Text( - widget.title!, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2, + child: Text( + widget.title!, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), const SizedBox( width: 50, diff --git a/lib/screens/backup_and_sync_webdav_screen.dart b/lib/screens/backup_and_sync_webdav_screen.dart index 5e9bf56..4a698fc 100644 --- a/lib/screens/backup_and_sync_webdav_screen.dart +++ b/lib/screens/backup_and_sync_webdav_screen.dart @@ -4,9 +4,10 @@ import 'dart:async'; import 'package:after_layout/after_layout.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; +import 'package:karing/app/local_services/vpn_service.dart'; import 'package:karing/app/modules/server_manager.dart'; import 'package:karing/app/modules/setting_manager.dart'; +import 'package:karing/app/runtime/return_result.dart'; import 'package:karing/app/utils/backup_and_sync_utils.dart'; import 'package:karing/app/utils/file_utils.dart'; import 'package:karing/app/utils/path_utils.dart'; @@ -40,6 +41,7 @@ class _BackupAndSyncWebdavScreenState bool _connecting = true; bool _loading = true; bool _uploading = false; + Client? _webdavClient; List _fileList = []; final TextEditingController _urlController = TextEditingController(); @@ -91,6 +93,7 @@ class _BackupAndSyncWebdavScreenState @override Widget build(BuildContext context) { final tcontext = Translations.of(context); + Size windowSize = MediaQuery.of(context).size; return Scaffold( appBar: PreferredSize( preferredSize: Size.zero, @@ -117,11 +120,16 @@ class _BackupAndSyncWebdavScreenState ), ), ), - Text( - tcontext.webdav, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 3, + child: Text( + tcontext.webdav, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), Row( children: [ @@ -309,9 +317,18 @@ class _BackupAndSyncWebdavScreenState _webdavClient = null; _fileList.clear(); setState(() {}); - - var result = await WebdavUtils.connect(settingConfig.webdav.url, - settingConfig.webdav.user, settingConfig.webdav.password); + List ports = await VPNService.getPortsByPrefer(false); + late ReturnResult result; + for (var port in ports) { + result = await WebdavUtils.connect(port, settingConfig.webdav.url, + settingConfig.webdav.user, settingConfig.webdav.password); + if (!mounted) { + return; + } + if (result.error == null) { + break; + } + } if (!mounted) { return; } @@ -322,7 +339,10 @@ class _BackupAndSyncWebdavScreenState DialogUtils.showAlertDialog( context, tcontext.BackupAndSyncWebdavScreen.webdavLoginFailed + - result.error!.message); + result.error!.message, + showCopy: true, + showFAQ: true, + withVersion: true); return; } _webdavClient = result.data; @@ -350,7 +370,10 @@ class _BackupAndSyncWebdavScreenState DialogUtils.showAlertDialog( context, tcontext.BackupAndSyncWebdavScreen.webdavListFailed + - result.error!.message); + result.error!.message, + showCopy: true, + showFAQ: true, + withVersion: true); return; } _fileList = result.data!; @@ -371,13 +394,15 @@ class _BackupAndSyncWebdavScreenState try { String dir = await PathUtils.cacheDir(); String filePath = path.join(dir, BackupAndSyncUtils.getZipFileName()); - var error = await ServerManager.backupToZip(filePath); + ReturnResultError? error = await ServerManager.backupToZip(filePath); if (!mounted) { FileUtils.deleteFileByPath(filePath); return; } if (error != null) { - DialogUtils.showAlertDialog(context, error.message); + DialogUtils.showAlertDialog(context, error.message, + showCopy: true, showFAQ: true, withVersion: true); + return; } error = await WebdavUtils.upload(_webdavClient!, relativePath: path.basename(filePath), localPath: filePath); @@ -389,7 +414,8 @@ class _BackupAndSyncWebdavScreenState _uploading = false; setState(() {}); if (error != null) { - DialogUtils.showAlertDialog(context, error.message); + DialogUtils.showAlertDialog(context, error.message, + showCopy: true, showFAQ: true, withVersion: true); return; } await list(); @@ -399,7 +425,8 @@ class _BackupAndSyncWebdavScreenState } _uploading = false; setState(() {}); - DialogUtils.showAlertDialog(context, err.toString()); + DialogUtils.showAlertDialog(context, err.toString(), + showCopy: true, showFAQ: true, withVersion: true); } } @@ -484,11 +511,12 @@ class _BackupAndSyncWebdavScreenState return false; } - SettingManager.getConfig().webdav.url = _urlController.text; + SettingManager.getConfig().webdav.url = + _urlController.text.trim(); SettingManager.getConfig().webdav.user = - _userController.text; + _userController.text.trim(); SettingManager.getConfig().webdav.password = - _passwordController.text; + _passwordController.text.trim(); SettingManager.saveConfig(); return true; @@ -529,7 +557,8 @@ class _BackupAndSyncWebdavScreenState return; } if (error != null) { - DialogUtils.showAlertDialog(context, error.message); + DialogUtils.showAlertDialog(context, error.message, + showCopy: true, showFAQ: true, withVersion: true); return; } await GroupHelper.backupRestoreFromZip(context, filePath, confirm: false); @@ -545,7 +574,8 @@ class _BackupAndSyncWebdavScreenState return; } if (error != null) { - DialogUtils.showAlertDialog(context, error.message); + DialogUtils.showAlertDialog(context, error.message, + showCopy: true, showFAQ: true, withVersion: true); return; } await list(); diff --git a/lib/screens/cloudflare_warp_account_screen.dart b/lib/screens/cloudflare_warp_account_screen.dart index 239b489..43d5fd0 100644 --- a/lib/screens/cloudflare_warp_account_screen.dart +++ b/lib/screens/cloudflare_warp_account_screen.dart @@ -56,6 +56,7 @@ class _CloudflareWarpAccountScreenState @override Widget build(BuildContext context) { final tcontext = Translations.of(context); + Size windowSize = MediaQuery.of(context).size; var settingConfig = SettingManager.getConfig(); return Scaffold( @@ -84,11 +85,16 @@ class _CloudflareWarpAccountScreenState ), ), ), - const Text( - "Account", - style: TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2, + child: const Text( + "Account", + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), Row( children: [ @@ -143,11 +149,14 @@ class _CloudflareWarpAccountScreenState .gen25PBWarpAccount(); if (account.error != null) { - if (!context.mounted) { + if (!mounted) { return; } DialogUtils.showAlertDialog( - context, account.error!.message); + context, account.error!.message, + showCopy: true, + showFAQ: true, + withVersion: true); } else { settingConfig.warp.account = account.data!; SettingManager.saveConfig(); diff --git a/lib/screens/common_dialog.dart b/lib/screens/common_dialog.dart index 54a811c..c3743d6 100644 --- a/lib/screens/common_dialog.dart +++ b/lib/screens/common_dialog.dart @@ -80,6 +80,6 @@ class CommonDialog { } DialogUtils.showAlertDialog(context, errMessage, - showCopy: true, withVersion: true); + showCopy: true, showFAQ: true, withVersion: true); } } diff --git a/lib/screens/dialog_utils.dart b/lib/screens/dialog_utils.dart index aa91b6f..517a6e5 100644 --- a/lib/screens/dialog_utils.dart +++ b/lib/screens/dialog_utils.dart @@ -17,11 +17,19 @@ class DialogUtilsResult { } class DialogUtils { + static Future Function()? faqCallback; + static Future showAlertDialog(BuildContext context, String text, - {bool showCopy = false, bool withVersion = false}) async { + {bool showCopy = false, + bool showFAQ = false, + bool withVersion = false}) async { if (!context.mounted) { return; } + double width = 60; + if (showCopy) { + width = 20; + } if (withVersion) { text = "${AppUtils.getBuildinVersion()}\n$text"; } @@ -62,6 +70,17 @@ class DialogUtils { Row( mainAxisAlignment: MainAxisAlignment.center, children: [ + ElevatedButton( + child: Text(tcontext.ok), + onPressed: () { + Navigator.pop(context); + }, + ), + showCopy + ? SizedBox( + width: width, + ) + : const SizedBox.shrink(), showCopy ? ElevatedButton( child: Text(tcontext.copy), @@ -72,19 +91,24 @@ class DialogUtils { }, ) : const SizedBox.shrink(), - showCopy - ? const SizedBox( - width: 60, - ) - : const SizedBox.shrink(), - ElevatedButton( - child: Text(tcontext.ok), - onPressed: () { - Navigator.pop(context); - }, - ), ], - ) + ), + const SizedBox( + height: 20, + ), + showFAQ + ? Padding( + padding: const EdgeInsets.fromLTRB(20, 0, 20, 0), + child: ElevatedButton( + child: Text(tcontext.faq), + onPressed: () async { + String? url = await faqCallback?.call(); + if (url != null) { + UrlLauncherUtils.loadUrl(url); + } + }, + )) + : const SizedBox.shrink(), ], ); }, diff --git a/lib/screens/diversion_group_custom_edit_screen.dart b/lib/screens/diversion_group_custom_edit_screen.dart index d467e1e..c61467f 100644 --- a/lib/screens/diversion_group_custom_edit_screen.dart +++ b/lib/screens/diversion_group_custom_edit_screen.dart @@ -478,6 +478,7 @@ class _DiversionGroupCustomEditScreenState @override Widget build(BuildContext context) { final tcontext = Translations.of(context); + Size windowSize = MediaQuery.of(context).size; return Scaffold( appBar: PreferredSize( preferredSize: Size.zero, @@ -504,11 +505,16 @@ class _DiversionGroupCustomEditScreenState ), ), ), - Text( - widget.name, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2, + child: Text( + widget.name, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), InkWell( onTap: () { diff --git a/lib/screens/diversion_group_custom_screen.dart b/lib/screens/diversion_group_custom_screen.dart index efcf9f0..32d6118 100644 --- a/lib/screens/diversion_group_custom_screen.dart +++ b/lib/screens/diversion_group_custom_screen.dart @@ -73,6 +73,7 @@ class _DiversionGroupCustomScreenState @override Widget build(BuildContext context) { final tcontext = Translations.of(context); + Size windowSize = MediaQuery.of(context).size; return Scaffold( appBar: PreferredSize( preferredSize: Size.zero, @@ -99,11 +100,16 @@ class _DiversionGroupCustomScreenState ), ), ), - Text( - tcontext.diversionCustomGroup, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2, + child: Text( + tcontext.diversionCustomGroup, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), InkWell( onTap: () { @@ -358,7 +364,8 @@ class _DiversionGroupCustomScreenState if (!mounted) { return; } - DialogUtils.showAlertDialog(context, result.error!.message); + DialogUtils.showAlertDialog(context, result.error!.message, + showCopy: true, showFAQ: true, withVersion: true); } if (!mounted) { @@ -381,9 +388,12 @@ class _DiversionGroupCustomScreenState if (!mounted) { return; } - DialogUtils.showAlertDialog(context, err.toString()); + DialogUtils.showAlertDialog(context, err.toString(), + showCopy: true, showFAQ: true, withVersion: true); + } + if (!mounted) { + return; } - _buildData(); setState(() {}); } @@ -430,7 +440,8 @@ class _DiversionGroupCustomScreenState if (!mounted) { return; } - DialogUtils.showAlertDialog(context, err.toString()); + DialogUtils.showAlertDialog(context, err.toString(), + showCopy: true, showFAQ: true, withVersion: true); } } diff --git a/lib/screens/diversion_rule_detect_screen.dart b/lib/screens/diversion_rule_detect_screen.dart index 1f17f01..3fa1289 100644 --- a/lib/screens/diversion_rule_detect_screen.dart +++ b/lib/screens/diversion_rule_detect_screen.dart @@ -109,6 +109,7 @@ class _DiversionRuleDetectScreenState @override Widget build(BuildContext context) { final tcontext = Translations.of(context); + Size windowSize = MediaQuery.of(context).size; return Scaffold( appBar: PreferredSize( preferredSize: Size.zero, @@ -133,11 +134,16 @@ class _DiversionRuleDetectScreenState ), ), ), - Text( - tcontext.DiversionRuleDetectScreen.title, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2, + child: Text( + tcontext.DiversionRuleDetectScreen.title, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), const SizedBox( width: 50, diff --git a/lib/screens/diversion_rules_custom_set_screen.dart b/lib/screens/diversion_rules_custom_set_screen.dart index 5bd228b..2d5e30b 100644 --- a/lib/screens/diversion_rules_custom_set_screen.dart +++ b/lib/screens/diversion_rules_custom_set_screen.dart @@ -85,8 +85,8 @@ class _DiversionRulesCustomSetScreenState ? 65 : 50), child: Text( - textAlign: TextAlign.center, widget.title, + textAlign: TextAlign.center, overflow: TextOverflow.ellipsis, style: const TextStyle( fontWeight: ThemeConfig.kFontWeightTitle, diff --git a/lib/screens/diversion_rules_screen.dart b/lib/screens/diversion_rules_screen.dart index c4b2d83..530f638 100644 --- a/lib/screens/diversion_rules_screen.dart +++ b/lib/screens/diversion_rules_screen.dart @@ -50,7 +50,7 @@ class DiversionRulesScreenState @override Widget build(BuildContext context) { final tcontext = Translations.of(context); - + Size windowSize = MediaQuery.of(context).size; return Scaffold( appBar: PreferredSize( preferredSize: Size.zero, @@ -77,11 +77,16 @@ class DiversionRulesScreenState ), ), ), - Text( - tcontext.diversionRules, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2, + child: Text( + tcontext.diversionRules, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), InkWell( onTap: () async { diff --git a/lib/screens/dns_auto_setup_screen.dart b/lib/screens/dns_auto_setup_screen.dart index 2bc4513..c21871f 100644 --- a/lib/screens/dns_auto_setup_screen.dart +++ b/lib/screens/dns_auto_setup_screen.dart @@ -61,6 +61,7 @@ class _DnsAutoSetupScreenState extends LasyRenderingState { @override Widget build(BuildContext context) { final tcontext = Translations.of(context); + Size windowSize = MediaQuery.of(context).size; return Scaffold( appBar: PreferredSize( preferredSize: Size.zero, @@ -87,11 +88,16 @@ class _DnsAutoSetupScreenState extends LasyRenderingState { ), ), ), - Text( - tcontext.SettingsScreen.dnsAutoSetServer, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2, + child: Text( + tcontext.SettingsScreen.dnsAutoSetServer, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), Row(children: [ _taskQueue != null diff --git a/lib/screens/dns_settings_screen.dart b/lib/screens/dns_settings_screen.dart index cb2973f..43e2da2 100644 --- a/lib/screens/dns_settings_screen.dart +++ b/lib/screens/dns_settings_screen.dart @@ -83,6 +83,7 @@ class _DnsSettingsScreenState extends LasyRenderingState { @override Widget build(BuildContext context) { + Size windowSize = MediaQuery.of(context).size; return Scaffold( appBar: PreferredSize( preferredSize: Size.zero, @@ -109,11 +110,16 @@ class _DnsSettingsScreenState extends LasyRenderingState { ), ), ), - Text( - widget.title, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2, + child: Text( + widget.title, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), Row(children: [ _taskQueue != null diff --git a/lib/screens/feedback_screen.dart b/lib/screens/feedback_screen.dart index 3333c76..09e2f33 100644 --- a/lib/screens/feedback_screen.dart +++ b/lib/screens/feedback_screen.dart @@ -47,6 +47,7 @@ class _SentryFeedbackScreenState extends LasyRenderingState { @override Widget build(BuildContext context) { final tcontext = Translations.of(context); + Size windowSize = MediaQuery.of(context).size; return Scaffold( appBar: PreferredSize( preferredSize: Size.zero, @@ -71,11 +72,16 @@ class _SentryFeedbackScreenState extends LasyRenderingState { ), ), ), - Text( - tcontext.feedback, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2, + child: Text( + tcontext.feedback, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), InkWell( onTap: () async { diff --git a/lib/screens/file_content_viewer_screen.dart b/lib/screens/file_content_viewer_screen.dart index bb84987..8c9f9c5 100644 --- a/lib/screens/file_content_viewer_screen.dart +++ b/lib/screens/file_content_viewer_screen.dart @@ -115,11 +115,16 @@ class FileContentViewerScreenState ), ), ), - Text( - tcontext.FileContentViewerScreen.title, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2, + child: Text( + tcontext.FileContentViewerScreen.title, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, diff --git a/lib/screens/group_helper.dart b/lib/screens/group_helper.dart index da6b7e2..9747a2e 100644 --- a/lib/screens/group_helper.dart +++ b/lib/screens/group_helper.dart @@ -22,6 +22,7 @@ import 'package:karing/app/utils/http_utils.dart'; import 'package:karing/app/utils/network_utils.dart'; import 'package:karing/app/utils/path_utils.dart'; import 'package:karing/app/utils/platform_utils.dart'; +import 'package:karing/app/utils/proxy_conf_utils.dart'; import 'package:karing/i18n/strings.g.dart'; import 'package:karing/screens/add_profile_by_import_from_file_screen.dart'; import 'package:karing/screens/add_profile_by_link_or_content_screen.dart'; @@ -38,9 +39,11 @@ import 'package:karing/screens/group_item.dart'; import 'package:karing/screens/group_options_helper.dart'; import 'package:karing/screens/group_screen.dart'; import 'package:karing/screens/home_tvos_screen.dart'; -import 'package:karing/screens/map_list_add_screen.dart'; +import 'package:karing/screens/list_add_screen.dart'; +import 'package:karing/screens/map_string_and_list_add_screen.dart'; import 'package:karing/screens/qrcode_scan_screen.dart'; import 'package:karing/screens/region_settings_screen.dart'; +import 'package:karing/screens/server_select_screen.dart'; import 'package:karing/screens/urltest_group_custom_screen.dart'; import 'package:path/path.dart' as path; import 'package:share_plus/share_plus.dart'; @@ -96,6 +99,60 @@ class GroupHelper { return userAgentSorted.join(";"); } + static Future showProxyFilter( + BuildContext context, ProxyFilter filter) async { + final tcontext = Translations.of(context); + ProxyFilter pf = ProxyFilter(); + pf.method = filter.method; + pf.keywordOrRegx = filter.keywordOrRegx; + Future> getOptions(BuildContext context) async { + List> tupleStrings = [ + Tuple2(ProxyFilterMethod.all.name, tcontext.all), + Tuple2(ProxyFilterMethod.include.name, tcontext.include), + Tuple2(ProxyFilterMethod.exclude.name, tcontext.exclude), + ]; + GroupItem options = GroupItem(options: [ + GroupItemOptions( + stringPickerOptions: GroupItemStringPickerOptions( + name: tcontext.filterMethod, + selected: pf.method.name, + tupleStrings: tupleStrings, + onPicker: (String? selected) async { + if (selected == ProxyFilterMethod.all.name) { + pf.method = ProxyFilterMethod.all; + } else if (selected == ProxyFilterMethod.include.name) { + pf.method = ProxyFilterMethod.include; + } else if (selected == ProxyFilterMethod.exclude.name) { + pf.method = ProxyFilterMethod.exclude; + } + })), + GroupItemOptions( + textFormFieldOptions: GroupItemTextFieldOptions( + name: tcontext.keywordOrRegx, + text: + pf.method != ProxyFilterMethod.all ? pf.keywordOrRegx : "", + textWidthPercent: 0.6, + enabled: pf.method != ProxyFilterMethod.all, + onChanged: (String value) { + pf.keywordOrRegx = value.trim(); + })), + ]); + + return [options]; + } + + await Navigator.push( + context, + MaterialPageRoute( + settings: GroupScreen.routSettings("ProxyFilter"), + builder: (context) => GroupScreen( + title: tcontext.filter, + getOptions: getOptions, + ))); + + return pf; + } + static Future showAddProfile(BuildContext context) async { Map tagSets = {}; for (var item in ServerManager.getConfig().items) { @@ -129,7 +186,8 @@ class GroupHelper { if (!context.mounted) { return; } - DialogUtils.showAlertDialog(context, err.toString()); + DialogUtils.showAlertDialog(context, err.toString(), + showCopy: true, showFAQ: true, withVersion: true); return; } if (!context.mounted) { @@ -231,7 +289,8 @@ class GroupHelper { DialogUtils.showLoadingDialog(context, text: ""); List urls = []; for (int i = 0; i < 5; ++i) { - urls.add("warp://auto?ifpd=10-20#Warp_$i"); + urls.add( + "warp://auto?ifp=8-15&ifps=40-100&ifpd=20-250#Warp_$i"); } var err = await ServerManager.addRemoteConfig( "", @@ -239,6 +298,7 @@ class GroupHelper { urls.join("\n"), SubscriptionLinkType.v2ray, "", + ProxyFilter(), false, null); if (!context.mounted) { @@ -246,7 +306,8 @@ class GroupHelper { } Navigator.pop(context); if (err != null) { - DialogUtils.showAlertDialog(context, err.message); + DialogUtils.showAlertDialog(context, err.message, + showCopy: true, showFAQ: true, withVersion: true); } else { DialogUtils.showAlertDialog( context, @@ -358,7 +419,7 @@ class GroupHelper { switchOptions: GroupItemSwitchOptions( name: tcontext.SettingsScreen.inboundDomainResolve, tips: tcontext.SettingsScreen.inboundDomainResolveTips( - p: settingConfig.proxy.mixedPort), + p: settingConfig.proxy.mixedRulePort), switchValue: settingConfig.dns.enableInboundDomainResolve, onSwitch: (bool value) async { settingConfig.dns.enableInboundDomainResolve = value; @@ -459,6 +520,7 @@ class GroupHelper { static Future showDeversion(BuildContext context) async { final tcontext = Translations.of(context); + var settingConfig = SettingManager.getConfig(); Future> getOptions(BuildContext context) async { country.Country? currentCountry = RegionSettingsScreen.getCurrentCountry(); @@ -488,8 +550,72 @@ class GroupHelper { await onTapRuleset(context); })), ]; + String frontProxy = ""; + if (settingConfig.frontProxy.isNotEmpty) { + frontProxy = settingConfig.frontProxy.length == 1 + ? settingConfig.frontProxy[0] + : "${settingConfig.frontProxy[0]}..."; + } List options2 = [ + !settingConfig.novice + ? GroupItemOptions( + pushOptions: GroupItemPushOptions( + name: tcontext.SettingsScreen.frontProxy, + tips: tcontext.SettingsScreen.frontProxyTips( + p: tcontext.outboundActionCurrentSelected), + text: frontProxy, + style: TextStyle( + fontFamily: Platform.isWindows ? 'Emoji' : null, + ), + onPush: () async { + String oldData = settingConfig.frontProxy.join(","); + List chain = settingConfig.frontProxy.toList(); + await Navigator.push( + context, + MaterialPageRoute( + settings: + ListAddScreen.routSettings("frontProxy"), + builder: (context) => ListAddScreen( + title: tcontext.server, + data: chain, + onTapAdd: () async { + ProxyConfig? result = await Navigator.push( + context, + MaterialPageRoute( + settings: ServerSelectScreen + .routSettings(), + builder: (context) => + ServerSelectScreen( + singleSelect: + ServerSelectScreenSingleSelectedOption( + selectedServer: + ProxyConfig(), + showNone: false, + showAutoSelect: false, + showUrltestGroup: false, + showFav: false, + showRecommend: false, + showRecent: false, + showTranffic: false, + showUpdate: false, + ), + multiSelect: null, + ))); + if (result == null || + result.groupid.isEmpty) { + return null; + } + + return result.tag; + }))); + String newData = chain.join(","); + if (oldData != newData) { + settingConfig.frontProxy = chain; + SettingManager.setDirty(true); + } + })) + : GroupItemOptions(), GroupItemOptions( pushOptions: GroupItemPushOptions( name: tcontext.urlTestCustomGroup, @@ -816,7 +942,7 @@ class GroupHelper { builder: (context) => const BackupAndSyncWebdavScreen())); } - static Future onTapLanSyncTo(BuildContext context) async { + static Future onTapLanSyncSendTo(BuildContext context) async { final tcontext = Translations.of(context); Future> getOptions(BuildContext context) async { List options = [ @@ -829,15 +955,14 @@ class GroupHelper { MaterialPageRoute( settings: BackupAndSyncLanSyncScreen.routSettings(), builder: (context) => BackupAndSyncLanSyncScreen( - title: tcontext.SettingsScreen.lanSyncTo, - syncUpload: false))); + title: tcontext.send, syncUpload: false))); })), PlatformUtils.isMobile() ? GroupItemOptions( pushOptions: GroupItemPushOptions( - name: tcontext.SettingsScreen.lanSyncScanQRcode, + name: tcontext.scanQrcode, onPush: () async { - onTapSyncByScanQRcode(context); + onTapSyncByScanQRcode(context, true); })) : GroupItemOptions(), ]; @@ -850,14 +975,14 @@ class GroupHelper { await Navigator.push( context, MaterialPageRoute( - settings: GroupScreen.routSettings("lanSyncTo"), + settings: GroupScreen.routSettings("send"), builder: (context) => GroupScreen( - title: tcontext.SettingsScreen.lanSyncTo, + title: tcontext.send, getOptions: getOptions, ))); } - static Future onTapLanSyncFrom(BuildContext context) async { + static Future onTapLanSyncReceiveFrom(BuildContext context) async { final tcontext = Translations.of(context); Future> getOptions(BuildContext context) async { List options = [ @@ -870,15 +995,14 @@ class GroupHelper { MaterialPageRoute( settings: BackupAndSyncLanSyncScreen.routSettings(), builder: (context) => BackupAndSyncLanSyncScreen( - title: tcontext.SettingsScreen.lanSyncFrom, - syncUpload: true))); + title: tcontext.receive, syncUpload: true))); })), PlatformUtils.isMobile() ? GroupItemOptions( pushOptions: GroupItemPushOptions( - name: tcontext.SettingsScreen.lanSyncScanQRcode, + name: tcontext.scanQrcode, onPush: () async { - onTapSyncByScanQRcode(context); + onTapSyncByScanQRcode(context, false); })) : GroupItemOptions(), ]; @@ -891,9 +1015,9 @@ class GroupHelper { await Navigator.push( context, MaterialPageRoute( - settings: GroupScreen.routSettings("lanSyncFrom"), + settings: GroupScreen.routSettings("receive"), builder: (context) => GroupScreen( - title: tcontext.SettingsScreen.lanSyncFrom, + title: tcontext.receive, getOptions: getOptions, ))); } @@ -905,17 +1029,17 @@ class GroupHelper { List options = [ GroupItemOptions( pushOptions: GroupItemPushOptions( - name: tcontext.SettingsScreen.lanSyncTo, + name: tcontext.send, onPush: !canzip ? null : () async { - onTapLanSyncTo(context); + onTapLanSyncSendTo(context); })), GroupItemOptions( pushOptions: GroupItemPushOptions( - name: tcontext.SettingsScreen.lanSyncFrom, + name: tcontext.receive, onPush: () async { - onTapLanSyncFrom(context); + onTapLanSyncReceiveFrom(context); })), ]; return [GroupItem(options: options)]; @@ -952,7 +1076,8 @@ class GroupHelper { return; } if (error != null) { - DialogUtils.showAlertDialog(context, error.message); + DialogUtils.showAlertDialog(context, error.message, + showCopy: true, showFAQ: true, withVersion: true); } else { DialogUtils.showAlertDialog( context, tcontext.SettingsScreen.importSuccess); @@ -961,7 +1086,7 @@ class GroupHelper { } static Future syncByScanQRcode( - BuildContext context, String qrcode) async { + BuildContext context, String qrcode, bool send) async { final tcontext = Translations.of(context); if (qrcode.isEmpty) { return; @@ -1001,10 +1126,12 @@ class GroupHelper { if (targetHost == null) { if (result != null && result.error != null) { DialogUtils.showAlertDialog( - context, tcontext.targetConnectFailed(p: result.error!.message)); + context, tcontext.targetConnectFailed(p: result.error!.message), + showCopy: true, showFAQ: true, withVersion: true); } else { DialogUtils.showAlertDialog( - context, tcontext.targetConnectFailed(p: ips)); + context, tcontext.targetConnectFailed(p: ips), + showCopy: true, showFAQ: true, withVersion: true); } return; } @@ -1012,6 +1139,12 @@ class GroupHelper { return; } if (uri.host == AppSchemeUtils.syncDownloadAction()) { + if (send) { + DialogUtils.showAlertDialog( + context, tcontext.sendOrReceiveNotMatch(p: tcontext.receive), + showCopy: false, showFAQ: true, withVersion: true); + return; + } if (filename.isEmpty) { return; } @@ -1024,14 +1157,14 @@ class GroupHelper { String dir = await PathUtils.cacheDir(); String zipPath = path.join(dir, filename); String url = "http://$targetHost:$iPort/${uri.host}"; - var result = await HttpUtils.httpDownload( + ReturnResult result = await HttpUtils.httpDownload( Uri.parse(url), zipPath, null, null, null); if (result.error != null) { if (!context.mounted) { return; } - DialogUtils.showAlertDialog(context, result.error.toString(), - showCopy: true, withVersion: true); + DialogUtils.showAlertDialog(context, result.error!.message, + showCopy: true, showFAQ: true, withVersion: true); return; } if (!context.mounted) { @@ -1039,37 +1172,46 @@ class GroupHelper { } await backupRestoreFromZip(context, zipPath, confirm: false); } else if (uri.host == AppSchemeUtils.syncUploadAction()) { - bool? ok = await DialogUtils.showConfirmDialog( - context, tcontext.SettingsScreen.syncToConfirm); + if (!send) { + DialogUtils.showAlertDialog( + context, tcontext.sendOrReceiveNotMatch(p: tcontext.send), + showCopy: true, showFAQ: true, withVersion: true); + return; + } + bool? ok = + await DialogUtils.showConfirmDialog(context, tcontext.sendConfirm); if (ok != true) { return; } String dir = await PathUtils.cacheDir(); String zipPath = path.join(dir, BackupAndSyncUtils.getZipFileName()); - var error = await ServerManager.backupToZip(zipPath); + ReturnResultError? error = await ServerManager.backupToZip(zipPath); if (error != null) { if (!context.mounted) { return; } - DialogUtils.showAlertDialog(context, error.toString(), - showCopy: true, withVersion: true); + DialogUtils.showAlertDialog(context, error.message, + showCopy: true, showFAQ: true, withVersion: true); return; } String url = "http://$targetHost:$iPort/${uri.host}"; - var err = await HttpUtils.httpUpload(Uri.parse(url), zipPath, null, null); + ReturnResultError? err = + await HttpUtils.httpUpload(Uri.parse(url), zipPath, null, null); FileUtils.deleteFileByPath(zipPath); if (!context.mounted) { return; } if (err != null) { - DialogUtils.showAlertDialog(context, err.message); + DialogUtils.showAlertDialog(context, err.message, + showCopy: true, showFAQ: true, withVersion: true); } else { - DialogUtils.showAlertDialog(context, tcontext.SettingsScreen.syncDone); + DialogUtils.showAlertDialog(context, tcontext.done); } } } - static Future onTapSyncByScanQRcode(BuildContext context) async { + static Future onTapSyncByScanQRcode( + BuildContext context, bool send) async { String? qrcode = await Navigator.push( context, MaterialPageRoute( @@ -1078,7 +1220,7 @@ class GroupHelper { if (!context.mounted) { return; } - await syncByScanQRcode(context, qrcode ?? ""); + await syncByScanQRcode(context, qrcode ?? "", send); } static Future showAppleTVByScanQRCode(BuildContext context) async { @@ -1164,10 +1306,12 @@ class GroupHelper { if (targetHost == null) { if (result != null && result.error != null) { DialogUtils.showAlertDialog( - context, tcontext.targetConnectFailed(p: result.error!.message)); + context, tcontext.targetConnectFailed(p: result.error!.message), + showCopy: true, showFAQ: true, withVersion: true); } else { DialogUtils.showAlertDialog( - context, tcontext.targetConnectFailed(p: ips)); + context, tcontext.targetConnectFailed(p: ips), + showCopy: true, showFAQ: true, withVersion: true); } return; @@ -1254,7 +1398,8 @@ class GroupHelper { if (!context.mounted) { return; } - DialogUtils.showAlertDialog(context, err.toString()); + DialogUtils.showAlertDialog(context, err.toString(), + showCopy: true, showFAQ: true, withVersion: true); } } @@ -1272,13 +1417,15 @@ class GroupHelper { } if (filePath != null) { - var error = await ServerManager.backupToZip(filePath); + ReturnResultError? error = await ServerManager.backupToZip(filePath); if (!context.mounted) { FileUtils.deleteFileByPath(filePath); return; } if (error != null) { - DialogUtils.showAlertDialog(context, error.message); + DialogUtils.showAlertDialog(context, error.message, + showCopy: true, showFAQ: true, withVersion: true); + return; } if (PlatformUtils.isMobile()) { try { @@ -1293,7 +1440,8 @@ class GroupHelper { if (!context.mounted) { return; } - DialogUtils.showAlertDialog(context, err.toString()); + DialogUtils.showAlertDialog(context, err.toString(), + showCopy: true, showFAQ: true, withVersion: true); } } @@ -1324,8 +1472,8 @@ class GroupHelper { await Navigator.push( context, MaterialPageRoute( - settings: MapListAddScreen.routSettings(), - builder: (context) => MapListAddScreen( + settings: MapStringAndListAddScreen.routSettings(), + builder: (context) => MapStringAndListAddScreen( title: tcontext.staticIP, data: hs, dialogTitle1: tcontext.domain, diff --git a/lib/screens/group_item.dart b/lib/screens/group_item.dart index 7d3f11f..e3b860d 100644 --- a/lib/screens/group_item.dart +++ b/lib/screens/group_item.dart @@ -356,8 +356,7 @@ class GroupItemCreator { child: InkWell( onTap: () { DialogUtils.showAlertDialog( - context, options.tips!, - showCopy: true, withVersion: true); + context, options.tips!); }, child: const Icon( Icons.info_outlined, @@ -836,8 +835,6 @@ class GroupItemCreator { Container _createGroupItemStringPicker(BuildContext context, double itemHeight, GroupItemStringPickerOptions options) { - Size windowSize = MediaQuery.of(context).size; - double textWidthPercent = options.textWidthPercent ?? 0.5; return Container( margin: const EdgeInsets.only(bottom: 1), child: Material( @@ -971,26 +968,6 @@ class GroupItemCreator { ); } - static List> _buildDropMenuList( - List? data, List>? dataTuple2) { - if (dataTuple2 != null) { - return dataTuple2.map((Tuple2 value) { - return DropdownMenuEntry( - value: value.item1, - label: value.item2, - ); - }).toList(); - } else if (data != null) { - return data.map((String value) { - return DropdownMenuEntry( - value: value, - label: value, - ); - }).toList(); - } - return []; - } - static List> _buildDropButtonList( List? data, List>? dataTuple2) { if (dataTuple2 != null) { diff --git a/lib/screens/group_screen.dart b/lib/screens/group_screen.dart index dcfa33a..ca90b96 100644 --- a/lib/screens/group_screen.dart +++ b/lib/screens/group_screen.dart @@ -1,6 +1,9 @@ // ignore_for_file: use_build_context_synchronously import 'package:flutter/material.dart'; +import 'package:karing/app/modules/setting_manager.dart'; +import 'package:karing/app/private/ads_banner_widget_private.dart'; +import 'package:karing/app/private/ads_private.dart'; import 'package:karing/screens/dialog_utils.dart'; import 'package:karing/screens/group_item.dart'; import 'package:karing/screens/theme_config.dart'; @@ -29,7 +32,8 @@ class GroupScreen extends LasyRenderingStatefulWidget { } class GroupScreenState extends LasyRenderingState { - //final FocusNode _focusNode = FocusNode(); + static int _adsCount = 0; + bool _hasAds = false; @override void initState() { super.initState(); @@ -37,33 +41,17 @@ class GroupScreenState extends LasyRenderingState { @override void dispose() { - //_focusNode.dispose(); + if (_hasAds) { + --GroupScreenState._adsCount; + _hasAds = false; + } + super.dispose(); } @override Widget build(BuildContext context) { Size windowSize = MediaQuery.of(context).size; - /*return KeyboardListener( - focusNode: _focusNode, - onKeyEvent: (KeyEvent event) { - if (event is KeyDownEvent) { - switch (event.logicalKey) { - case LogicalKeyboardKey.arrowDown: - break; - case LogicalKeyboardKey.arrowLeft: - break; - case LogicalKeyboardKey.arrowRight: - break; - case LogicalKeyboardKey.arrowUp: - break; - case LogicalKeyboardKey.enter: //KEY_UP - //FocusScope.of(context).requestFocus(_focusNode); - break; - } - } else if (event is KeyUpEvent) {} - }, - child:*/ return Scaffold( appBar: PreferredSize( preferredSize: Size.zero, @@ -99,6 +87,7 @@ class GroupScreenState extends LasyRenderingState { child: Text( widget.title, textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, style: const TextStyle( fontWeight: ThemeConfig.kFontWeightTitle, fontSize: ThemeConfig.kFontSizeTitle), @@ -149,14 +138,31 @@ class GroupScreenState extends LasyRenderingState { Expanded( child: SingleChildScrollView( child: FutureBuilder( - future: getGroupOptions(), + future: getGroupOptionsWithTryCatch(), builder: (BuildContext context, AsyncSnapshot> snapshot) { List data = snapshot.hasData ? snapshot.data! : []; - return Column( - children: - GroupItemCreator.createGroups(context, data)); + List children = []; + if (AdsPrivate.getEnable() && + (_hasAds || GroupScreenState._adsCount < 1)) { + if (!_hasAds) { + ++GroupScreenState._adsCount; + _hasAds = true; + } + var settingConfig = SettingManager.getConfig(); + var expire = DateTime.tryParse( + settingConfig.ads.bannerRewardExpire); + if (expire == null || DateTime.now().isAfter(expire)) { + children.add(AdsBannerWidget( + adWidth: windowSize.width, + bannerName: "banner3")); + children.add(const SizedBox(height: 20)); + } + } + children + .addAll(GroupItemCreator.createGroups(context, data)); + return Column(children: children); }, ), ), @@ -166,7 +172,20 @@ class GroupScreenState extends LasyRenderingState { ), ), ); - //); + } + + Future> getGroupOptionsWithTryCatch() async { + try { + return await getGroupOptions(); + } catch (err, stacktrace) { + if (!mounted) { + return []; + } + DialogUtils.showAlertDialog( + context, "${err.toString()}\n${stacktrace.toString()}", + showCopy: true, showFAQ: true, withVersion: true); + return []; + } } Future> getGroupOptions() async { diff --git a/lib/screens/home_screen.dart b/lib/screens/home_screen.dart index 1faad88..532f374 100644 --- a/lib/screens/home_screen.dart +++ b/lib/screens/home_screen.dart @@ -6,7 +6,6 @@ import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:flutter/widgets.dart'; import 'package:flutter_inapp_notifications/flutter_inapp_notifications.dart'; import 'package:karing/app/local_services/vpn_service.dart'; import 'package:karing/app/modules/app_lifecycle_state_notify_manager.dart'; @@ -15,8 +14,11 @@ import 'package:karing/app/modules/app_lifecycle_state_notify_manager.dart'; import 'package:karing/app/modules/auto_update_manager.dart'; import 'package:karing/app/modules/biz.dart'; import 'package:karing/app/modules/notice_manager.dart'; +import 'package:karing/app/modules/proxy_cluster.dart'; +import 'package:karing/app/modules/remote_config_manager.dart'; import 'package:karing/app/modules/server_manager.dart'; import 'package:karing/app/modules/setting_manager.dart'; +import 'package:karing/app/private/ads_banner_widget_private.dart'; import 'package:karing/app/runtime/return_result.dart'; import 'package:karing/app/utils/analytics_utils.dart'; import 'package:karing/app/utils/app_scheme_utils.dart'; @@ -25,7 +27,7 @@ import 'package:karing/app/utils/clash_api.dart'; import 'package:karing/app/utils/diversion_custom_utils.dart'; import 'package:karing/app/utils/error_reporter_utils.dart'; import 'package:karing/app/utils/file_utils.dart'; -import 'package:karing/app/utils/google_admob.dart'; + import 'package:karing/app/utils/http_utils.dart'; import 'package:karing/app/utils/karing_url_utils.dart'; import 'package:karing/app/utils/local_notifications_utils.dart'; @@ -35,7 +37,6 @@ import 'package:karing/app/utils/main_channel_utils.dart'; import 'package:karing/app/utils/path_utils.dart'; import 'package:karing/app/utils/platform_utils.dart'; import 'package:karing/app/utils/proxy_conf_utils.dart'; -import 'package:karing/app/utils/sentry_utils.dart'; import 'package:karing/app/utils/singbox_config_builder.dart'; import 'package:karing/app/utils/system_scheme_utils.dart'; import 'package:karing/app/utils/url_launcher_utils.dart'; @@ -68,7 +69,6 @@ import 'package:move_to_background/move_to_background.dart'; import 'package:path/path.dart' as path; import 'package:protocol_handler/protocol_handler.dart'; import 'package:provider/provider.dart'; -import 'package:sentry_flutter/sentry_flutter.dart'; import 'package:vpn_service/state.dart'; import 'package:web_socket_channel/io.dart'; @@ -99,7 +99,9 @@ class _HomeScreenState extends LasyRenderingState static const String kLocalNotificationsIdNetState = "netState"; static const String kLocalNotificationsIdVpnState = "vpnState"; + final FocusNode _focusNodeSettings = FocusNode(); final FocusNode _focusNodeSwitch = FocusNode(); + final FocusNode _focusNodeSelect = FocusNode(); HttpClient? _httpClient; StreamSubscription? _subscriptions; bool _wsConnecting = false; @@ -141,14 +143,13 @@ class _HomeScreenState extends LasyRenderingState ProxyConfig _currentServer = ProxyConfig(); bool _inAppNotificationsShowing = false; - DateTime? _bannerExpire; - @override void initState() { super.initState(); WidgetsBinding.instance.addObserver(this); protocolHandler.addListener(this); + _init(); Biz.initHomeFinish(); ErrorReporterUtils.register(() { @@ -156,7 +157,8 @@ class _HomeScreenState extends LasyRenderingState return; } final tcontext = Translations.of(context); - DialogUtils.showAlertDialog(context, tcontext.HomeScreen.deviceNoSpace); + DialogUtils.showAlertDialog(context, tcontext.HomeScreen.deviceNoSpace, + showCopy: true, showFAQ: true, withVersion: true); }); Future.delayed(const Duration(seconds: 0), () async { @@ -166,11 +168,6 @@ class _HomeScreenState extends LasyRenderingState LocalNotifications.init(); } - @override - void didChangeDependencies() { - super.didChangeDependencies(); - } - Future futureBool(bool value) async { return value; } @@ -182,12 +179,12 @@ class _HomeScreenState extends LasyRenderingState value = await LocalStorage.read(idKey); } catch (e) { DialogUtils.showAlertDialog(context, e.toString(), - showCopy: true, withVersion: true); + showCopy: true, showFAQ: true, withVersion: true); return; } if (value == null) { - final tcontext = Translations.of(context); + var tcontext = Translations.of(context); await Navigator.push( context, MaterialPageRoute( @@ -204,6 +201,7 @@ class _HomeScreenState extends LasyRenderingState canGoBack: false, nextText: tcontext.next, ))); + tcontext = Translations.of(context); await Navigator.push( context, @@ -275,11 +273,10 @@ class _HomeScreenState extends LasyRenderingState "currentSelectorTag": _currentServerForSelector.now, }); - String msg = - content.replaceAll("sing-box-clone", "").replaceAll("sing-box", ""); + String msg = content.replaceAll("sing-box", ""); await DialogUtils.showAlertDialog(context, msg, - showCopy: true, withVersion: true); + showCopy: true, showFAQ: true, withVersion: true); } } @@ -554,6 +551,14 @@ class _HomeScreenState extends LasyRenderingState void _init() async { Biz.onInitFinish(() async { + DialogUtils.faqCallback = () async { + var remoteConfig = RemoteConfigManager.getConfig(); + String queryParams = await KaringUrlUtils.getQueryParams(); + return UrlLauncherUtils.reorganizationUrl( + remoteConfig.faq, queryParams) ?? + remoteConfig.faq; + }; + checkError("onInitFinish"); if (_currentServer.tag.isEmpty) { @@ -898,7 +903,6 @@ class _HomeScreenState extends LasyRenderingState _canConnect = _isStarted; } _showNotify(); - _loadBannerAd(true); }); AppLifecycleStateNofityManager.onStatePaused(hashCode, () async { @@ -908,8 +912,8 @@ class _HomeScreenState extends LasyRenderingState }); if (Platform.isWindows) { - bool reg = await SystemSchemeUtils.isRegistered( - SystemSchemeUtils.getClashScheme()); + bool reg = + SystemSchemeUtils.isRegistered(SystemSchemeUtils.getClashScheme()); if (!reg) { SystemSchemeUtils.register(SystemSchemeUtils.getClashScheme()); } @@ -924,7 +928,7 @@ class _HomeScreenState extends LasyRenderingState options.invalidServerError = tcontext.HomeScreen.invalidServer; options.expiredServerError = tcontext.HomeScreen.expiredServer; ReturnResultError? err = await VPNService.setServer( - _currentServer, options, SingboxExportType.karing, "", savePath); + _currentServer, options, SingboxExportType.karing, null, "", savePath); if (err != null) { return err; } @@ -955,6 +959,7 @@ class _HomeScreenState extends LasyRenderingState if (!run) { return; } + await ProxyCluster.stop(); _disconnectToCurrent(); _disconnectToService(); _currentServerForSelector.clear(); @@ -976,10 +981,21 @@ class _HomeScreenState extends LasyRenderingState parameters: { "err": err.message, "from": from, + "tunMode": await VPNService.getTunMode(), "currentSelectorTag": _currentServerForSelector.now, }); CommonDialog.handleStartError(context, err.message); } + if (PlatformUtils.isPC()) { + var settingConfig = SettingManager.getConfig(); + if (settingConfig.proxy.enableCluster) { + String? error = await ProxyCluster.start(); + if (error != null) { + DialogUtils.showAlertDialog(context, error, + showCopy: true, showFAQ: true, withVersion: true); + } + } + } } else { _isStarting = false; _isStarted = false; @@ -1051,6 +1067,7 @@ class _HomeScreenState extends LasyRenderingState return Material( color: Colors.grey.withOpacity(0.5), child: InkWell( + focusNode: _focusNodeSelect, onTap: setting.originSBProfile.isNotEmpty ? null : () async { @@ -1127,7 +1144,10 @@ class _HomeScreenState extends LasyRenderingState setState(() {}); if (err != null) { DialogUtils.showAlertDialog( - context, err.message); + context, err.message, + showCopy: true, + showFAQ: true, + withVersion: true); } }); }, @@ -1437,14 +1457,9 @@ class _HomeScreenState extends LasyRenderingState } Future onLongPressNetConnections() async { - var result = await ClashApi.resetOutboundConnections( + await ClashApi.resetOutboundConnections( SettingManager.getConfig().proxy.controlPort, ); - if (result.error != null) { - DialogUtils.showAlertDialog(context, result.error!.message); - } else { - DialogUtils.showAlertDialog(context, "outbound connections reseted"); - } } Future onTapServerSelect() async { @@ -1521,6 +1536,7 @@ class _HomeScreenState extends LasyRenderingState Future stop() async { _currentServerForSelector.clear(); + await ProxyCluster.stop(); if (_currentServer.groupid == ServerManager.getUrltestGroupId()) { _currentServer.latency = ""; _currentServerForSelector.history.clear(); @@ -1550,6 +1566,39 @@ class _HomeScreenState extends LasyRenderingState Future start(String from, {bool disableShowAlertDialog = false}) async { _currentServerForSelector.clear(); + await ProxyCluster.stop(); + if (Platform.isWindows) { + List filePaths = [ + PathUtils.serviceExePath(), + ]; + List dirPaths = [PathUtils.flutterAssetsDir()]; + for (var filePath in filePaths) { + var file = File(filePath); + bool exist = await file.exists(); + if (!exist) { + final tcontext = Translations.of(context); + if (!disableShowAlertDialog) { + DialogUtils.showAlertDialog( + context, tcontext.fileNotExistReinstall(p: filePath), + showCopy: true, showFAQ: true, withVersion: true); + } + return ReturnResultError(tcontext.fileNotExistReinstall(p: filePath)); + } + } + for (var filePath in dirPaths) { + var file = Directory(filePath); + bool exist = await file.exists(); + if (!exist) { + final tcontext = Translations.of(context); + if (!disableShowAlertDialog) { + DialogUtils.showAlertDialog( + context, tcontext.fileNotExistReinstall(p: filePath), + showCopy: true, showFAQ: true, withVersion: true); + } + return ReturnResultError(tcontext.fileNotExistReinstall(p: filePath)); + } + } + } bool noConfig = ServerManager.getConfig().getServersCount(false) == 0; if (noConfig) { Log.w("start failed: no server avaliable, from $from"); @@ -1578,6 +1627,15 @@ class _HomeScreenState extends LasyRenderingState Biz.vpnStateChanged(_isStarted); _canConnect = _isStarted; setState(() {}); + AnalyticsUtils.logEvent( + analyticsEventType: analyticsEventTypeApp, + name: 'HSS_start', + parameters: { + "err": err.message, + "from": from, + "tunMode": await VPNService.getTunMode(), + "currentSelectorTag": _currentServerForSelector.now, + }); if (!disableShowAlertDialog) { CommonDialog.handleStartError(context, err.message); } @@ -1599,12 +1657,26 @@ class _HomeScreenState extends LasyRenderingState parameters: { "err": (err != null) ? err.message : null, "from": from, + "tunMode": await VPNService.getTunMode(), "currentSelectorTag": _currentServerForSelector.now, }); if (err != null) { if (!disableShowAlertDialog) { CommonDialog.handleStartError(context, err.message); } + } else { + if (PlatformUtils.isPC()) { + var settingConfig = SettingManager.getConfig(); + if (settingConfig.proxy.enableCluster) { + String? error = await ProxyCluster.start(); + if (error != null) { + if (!disableShowAlertDialog) { + DialogUtils.showAlertDialog(context, error, + showCopy: true, showFAQ: true, withVersion: true); + } + } + } + } } return err; } @@ -1629,14 +1701,24 @@ class _HomeScreenState extends LasyRenderingState } void installConfig(Uri uri) async { - String? name = uri.queryParameters["name"] ?? uri.fragment; - String? url = uri.queryParameters["url"]; - String? ispName = - uri.queryParameters["isp-name"] ?? uri.queryParameters["Isp-Name"]; - String? ispUrl = - uri.queryParameters["isp-url"] ?? uri.queryParameters["Isp-Url"]; - String? ispFaq = - uri.queryParameters["isp-faq"] ?? uri.queryParameters["Isp-Faq"]; + String? name; + String? url; + String? ispName; + String? ispUrl; + String? ispFaq; + try { + name = uri.queryParameters["name"]; + url = uri.queryParameters["url"]; + ispName = + uri.queryParameters["isp-name"] ?? uri.queryParameters["Isp-Name"]; + ispUrl = uri.queryParameters["isp-url"] ?? uri.queryParameters["Isp-Url"]; + ispFaq = uri.queryParameters["isp-faq"] ?? uri.queryParameters["Isp-Faq"]; + } catch (err) { + DialogUtils.showAlertDialog(context, err.toString(), + showCopy: true, showFAQ: true, withVersion: true); + return; + } + name ??= uri.fragment; if (name.isNotEmpty) { try { name = Uri.decodeComponent(name); @@ -1682,7 +1764,8 @@ class _HomeScreenState extends LasyRenderingState } Navigator.pop(context); if (result.error != null) { - DialogUtils.showAlertDialog(context, result.error!.message); + DialogUtils.showAlertDialog(context, result.error!.message, + showCopy: true, showFAQ: true, withVersion: true); return; } await GroupHelper.backupRestoreFromZip(context, filePath, confirm: false); @@ -1737,9 +1820,9 @@ class _HomeScreenState extends LasyRenderingState @override void dispose() { - _bannerAd?.dispose(); - _rewardedAd?.dispose(); + _focusNodeSettings.dispose(); _focusNodeSwitch.dispose(); + _focusNodeSelect.dispose(); ErrorReporterUtils.register(null); _timer?.cancel(); _timer = null; @@ -1754,154 +1837,190 @@ class _HomeScreenState extends LasyRenderingState @override Widget build(BuildContext context) { final tcontext = Translations.of(context); + Size windowSize = MediaQuery.of(context).size; var settingConfig = SettingManager.getConfig(); AutoUpdateCheckVersion checkVersion = AutoUpdateManager.getVersionCheck(); NoticeItem? noticeItem = NoticeManager.getNotice().getFirstUnread(); bool noConfig = ServerManager.getConfig().getServersCount(false) == 0; - Size windowSize = MediaQuery.of(context).size; + var expire = DateTime.tryParse(settingConfig.ads.bannerRewardExpire); + bool showAds = expire == null || DateTime.now().isAfter(expire); var themes = Provider.of(context, listen: false); Color? color = themes.getThemeHomeColor(context); - return Scaffold( - appBar: PreferredSize( - preferredSize: Size.zero, - child: AppBar( - backgroundColor: color, - systemOverlayStyle: SystemUiOverlayStyle( - systemNavigationBarIconBrightness: - themes.getStatusBarIconBrightness(context), - systemNavigationBarColor: color, - systemNavigationBarDividerColor: Colors.transparent, - statusBarColor: color, - statusBarBrightness: themes.getStatusBarBrightness(context), - statusBarIconBrightness: themes.getStatusBarIconBrightness(context), - ), - ), - ), - backgroundColor: color, - body: SafeArea( - child: Column( - children: [ - Container( - padding: const EdgeInsets.fromLTRB(0, 20, 0, 0), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row(mainAxisAlignment: MainAxisAlignment.start, children: [ - Tooltip( - message: tcontext.setting, - child: InkWell( - onTap: () async { - onTapSetting(); - }, - child: Stack( - children: [ - const SizedBox( - width: 50, - height: 30, - child: Icon( - Icons.settings_outlined, - size: 26, - ), - ), - checkVersion.newVersion || noticeItem != null - ? Positioned( - left: 10, - top: 0, - child: Container( - width: 8, - height: 8, - decoration: const BoxDecoration( - color: Colors.red, - shape: BoxShape.circle, - )), - ) - : const SizedBox( - width: 0, - ), - ], - ))), - Row(children: createToolbar()), - ]), - Tooltip( - message: tcontext.SettingsScreen.theme, - child: InkWell( - onTap: () async { - onTapSetTheme(); - }, - child: const SizedBox( - width: 50, - height: 30, - child: Icon( - Icons.color_lens_outlined, - size: 26, - ), - ), - ), - ) - ], + return Focus( + autofocus: true, + includeSemantics: true, + onKeyEvent: (FocusNode node, KeyEvent event) { + if (event is KeyDownEvent) { + switch (event.logicalKey) { + case LogicalKeyboardKey.contextMenu: + var focus = [ + _focusNodeSettings, + _focusNodeSwitch, + _focusNodeSelect + ]; + int? focusIndex; + for (int i = 0; i < focus.length; ++i) { + if (focus[i].hasFocus) { + focusIndex = i; + break; + } + } + if (focusIndex == null) { + _focusNodeSwitch.requestFocus(); + } else { + focus[(focusIndex + 1) % focus.length].requestFocus(); + } + + return KeyEventResult.handled; + } + } + return KeyEventResult.ignored; + }, + child: Scaffold( + appBar: PreferredSize( + preferredSize: Size.zero, + child: AppBar( + backgroundColor: color, + systemOverlayStyle: SystemUiOverlayStyle( + systemNavigationBarIconBrightness: + themes.getStatusBarIconBrightness(context), + systemNavigationBarColor: color, + systemNavigationBarDividerColor: Colors.transparent, + statusBarColor: color, + statusBarBrightness: themes.getStatusBarBrightness(context), + statusBarIconBrightness: + themes.getStatusBarIconBrightness(context), ), ), - Expanded( - child: SingleChildScrollView( - child: Column( - children: [ - const SizedBox( - height: 20, - ), - _bannerAdIsLoaded && _bannerAd != null - ? SizedBox( - height: _bannerAd!.size.height.toDouble(), - width: _bannerAd!.size.width.toDouble(), - child: AdWidget(ad: _bannerAd!)) - : const SizedBox.shrink(), - Container( - alignment: Alignment.center, - child: Stack(children: [ - SizedBox( - width: 180, - child: FittedBox( - fit: BoxFit.fill, - child: Switch.adaptive( - value: _isStarted, - //autofocus: Platform.isAndroid, - activeColor: ThemeDefine.kColorGreenBright, - thumbColor: - WidgetStateProperty.resolveWith( - (Set states) { - return Colors.orange; - }), - inactiveTrackColor: noConfig - ? Colors.grey - : Colors.grey.withOpacity(0.5), - onChanged: (bool newValue) async { - if (noConfig) { - onTapToggleStart(); - } else { - if (!_isStarting && !_isStoping) { - onTapToggle(); - } - } - }, + ), + backgroundColor: color, + body: SafeArea( + child: Column( + children: [ + Container( + padding: const EdgeInsets.fromLTRB(0, 20, 0, 0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Tooltip( + message: tcontext.setting, + child: InkWell( + focusNode: _focusNodeSettings, + onTap: () async { + onTapSetting(); + }, + child: Stack( + children: [ + const SizedBox( + width: 50, + height: 30, + child: Icon( + Icons.settings_outlined, + size: 26, + ), + ), + checkVersion.newVersion || + noticeItem != null + ? Positioned( + left: 10, + top: 0, + child: Container( + width: 8, + height: 8, + decoration: + const BoxDecoration( + color: Colors.red, + shape: BoxShape.circle, + )), + ) + : const SizedBox( + width: 0, + ), + ], + ))), + Row(children: createToolbar()), + ]), + Tooltip( + message: tcontext.SettingsScreen.theme, + child: InkWell( + onTap: () async { + onTapSetTheme(); + }, + child: const SizedBox( + width: 50, + height: 30, + child: Icon( + Icons.color_lens_outlined, + size: 26, ), ), ), - SizedBox( - width: 150, - height: 150, - child: _isStarting || _isStoping - ? Container( - alignment: const Alignment(-0.25, 0), - child: const RepaintBoundary( - child: CircularProgressIndicator( - color: - ThemeDefine.kColorGreenBright)), - ) - : null), - ]), - ), - /*AnimatedToggleSwitch.dual( + ) + ], + ), + ), + Expanded( + child: SingleChildScrollView( + child: Column( + children: [ + const SizedBox( + height: 20, + ), + AdsBannerWidget( + adWidth: windowSize.width, + mask: showAds ? null : color, + ), + Container( + alignment: Alignment.center, + child: Stack(children: [ + SizedBox( + width: 180, + child: FittedBox( + fit: BoxFit.fill, + child: Switch.adaptive( + value: _isStarted, + focusNode: _focusNodeSwitch, + activeColor: ThemeDefine.kColorGreenBright, + thumbColor: + WidgetStateProperty.resolveWith( + (Set states) { + return Colors.orange; + }), + inactiveTrackColor: noConfig + ? Colors.grey + : Colors.grey.withOpacity(0.5), + onChanged: (bool newValue) async { + if (noConfig) { + onTapToggleStart(); + } else { + if (!_isStarting && !_isStoping) { + onTapToggle(); + } + } + }, + ), + ), + ), + SizedBox( + width: 150, + height: 150, + child: _isStarting || _isStoping + ? Container( + alignment: const Alignment(-0.25, 0), + child: const RepaintBoundary( + child: CircularProgressIndicator( + color: ThemeDefine + .kColorGreenBright)), + ) + : null), + ]), + ), + /*AnimatedToggleSwitch.dual( current: _isStarted, first: false, second: true, @@ -1964,142 +2083,147 @@ class _HomeScreenState extends LasyRenderingState const SizedBox( height: 35, ),*/ - Column( - children: [ - Platform.isWindows || - Platform.isMacOS || - Platform.isLinux - ? Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Row( - mainAxisAlignment: MainAxisAlignment.center, + Column( + children: [ + Platform.isWindows || + Platform.isMacOS || + Platform.isLinux + ? Column( + crossAxisAlignment: + CrossAxisAlignment.center, children: [ - Tooltip( - message: tcontext.HomeScreen - .systemProxyTips( - hp: settingConfig - .proxy.mixedPort, - sp: settingConfig - .proxy.mixedPort), - child: InkWell( - onTap: () { - DialogUtils.showAlertDialog( - context, - tcontext.HomeScreen - .systemProxyTips( - hp: settingConfig - .proxy.mixedPort, - sp: settingConfig - .proxy - .mixedPort)); - }, - child: const Icon( - Icons.info_outlined, - size: 20, + Row( + mainAxisAlignment: + MainAxisAlignment.center, + children: [ + Tooltip( + message: tcontext.HomeScreen + .systemProxyTips( + hp: settingConfig + .proxy.mixedRulePort, + sp: settingConfig + .proxy.mixedRulePort), + child: InkWell( + onTap: () { + DialogUtils.showAlertDialog( + context, + tcontext.HomeScreen + .systemProxyTips( + hp: settingConfig + .proxy + .mixedRulePort, + sp: settingConfig + .proxy + .mixedRulePort)); + }, + child: const Icon( + Icons.info_outlined, + size: 20, + ), + )), + const SizedBox( + width: 15, + ), + Text( + tcontext.systemProxy, + style: const TextStyle( + fontSize: + ThemeConfig.kFontSizeListItem, ), - )), - const SizedBox( - width: 15, + ), + FutureBuilder( + future: getSystemProxy(), + builder: (BuildContext context, + AsyncSnapshot snapshot) { + return Switch.adaptive( + value: snapshot.hasData && + snapshot.data!, + activeColor: ThemeDefine + .kColorGreenBright, + onChanged: noConfig + ? null + : (bool newValue) { + if (!_isStarting && + !_isStoping) { + VPNService + .setSystemProxy( + newValue); + setState(() {}); + } + }, + ); + }, + ), + ], ), - Text( - tcontext.systemProxy, + ], + ) + : const SizedBox.shrink(), + const SizedBox( + height: 10, + ), + SizedBox( + child: SegmentedButton( + segments: >[ + ButtonSegment( + value: false, + label: Text( + tcontext.rule, style: const TextStyle( fontSize: - ThemeConfig.kFontSizeListItem, + ThemeConfig.kFontSizeListSubItem, ), - ), - FutureBuilder( - future: getSystemProxy(), - builder: (BuildContext context, - AsyncSnapshot snapshot) { - return Switch.adaptive( - value: snapshot.hasData && - snapshot.data!, - activeColor: - ThemeDefine.kColorGreenBright, - onChanged: noConfig - ? null - : (bool newValue) { - if (!_isStarting && - !_isStoping) { - VPNService.setSystemProxy( - newValue); - setState(() {}); - } - }, - ); - }, - ), - ], - ), + )), + ButtonSegment( + value: true, + label: Text( + tcontext.global, + style: const TextStyle( + fontSize: + ThemeConfig.kFontSizeListSubItem, + ), + )), ], - ) - : const SizedBox.shrink(), - const SizedBox( - height: 10, - ), - SizedBox( - child: SegmentedButton( - segments: >[ - ButtonSegment( - value: false, - label: Text( - tcontext.rule, - style: const TextStyle( - fontSize: - ThemeConfig.kFontSizeListSubItem, - ), - )), - ButtonSegment( - value: true, - label: Text( - tcontext.global, - style: const TextStyle( - fontSize: - ThemeConfig.kFontSizeListSubItem, - ), - )), - ], - selected: {SettingManager.getConfig().proxyAll}, - onSelectionChanged: (Set newSelection) async { - SettingManager.getConfig().proxyAll = - newSelection.first; - SettingManager.saveConfig(); - setState(() {}); - await setServerAndReload("proxyAll"); - }, - multiSelectionEnabled: false, - ), - ), - const SizedBox( - height: 10, - ), - Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - createGroupTraffic(context), - ]), - const SizedBox( - height: 10, + selected: {SettingManager.getConfig().proxyAll}, + onSelectionChanged: + (Set newSelection) async { + SettingManager.getConfig().proxyAll = + newSelection.first; + SettingManager.saveConfig(); + setState(() {}); + await setServerAndReload("proxyAll"); + }, + multiSelectionEnabled: false, + ), + ), + const SizedBox( + height: 10, + ), + Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + createGroupTraffic(context), + ]), + const SizedBox( + height: 10, + ), + createNetStatusChart(context), + ], ), - createNetStatusChart(context), ], ), - ], + ), ), - ), - ), - Column( - children: [createServerSelect(context)], - ), - const SizedBox( - height: 20, + Column( + children: [createServerSelect(context)], + ), + const SizedBox( + height: 20, + ), + ], ), - ], - ), - ), - ); + ), + )); } List createToolbar() { @@ -2323,12 +2447,13 @@ class _HomeScreenState extends LasyRenderingState if (value != null) { DialogUtils.showAlertDialog( context, tcontext.updateFailed(p: value.message), - showCopy: true, withVersion: true); + showCopy: true, showFAQ: true, withVersion: true); } }); } else { DialogUtils.showAlertDialog( - context, tcontext.updateFailed(p: value.error!.message)); + context, tcontext.updateFailed(p: value.error!.message), + showCopy: true, showFAQ: true, withVersion: true); } } }) diff --git a/lib/screens/home_tvos_screen.dart b/lib/screens/home_tvos_screen.dart index a92e852..581e744 100644 --- a/lib/screens/home_tvos_screen.dart +++ b/lib/screens/home_tvos_screen.dart @@ -83,9 +83,9 @@ class _HomeTVOSScreenState extends LasyRenderingState String _startDurationNotify = "0 B/s"; Function(List)? _trackerCallback; - bool _isStarting = false; + /*bool _isStarting = false; bool _isStarted = false; - bool _isStoping = false; + bool _isStoping = false;*/ @override void initState() { super.initState(); @@ -191,11 +191,8 @@ class _HomeTVOSScreenState extends LasyRenderingState _trackerCallback!(con.connections); } }, onDone: () { - print('ws channel closed'); _disconnectToService(); - }, onError: (error) { - print(error); - }); + }, onError: (error) {}); } } catch (err) { Log.w("_connectToService exception ${err.toString()}"); @@ -280,7 +277,6 @@ class _HomeTVOSScreenState extends LasyRenderingState @override Widget build(BuildContext context) { final tcontext = Translations.of(context); - Size windowSize = MediaQuery.of(context).size; var themes = Provider.of(context, listen: false); Color? color = themes.getThemeHomeColor(context); @@ -314,11 +310,16 @@ class _HomeTVOSScreenState extends LasyRenderingState ), ), ), - Text( - tcontext.appleTV, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 3, + child: Text( + tcontext.appleTV, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -669,13 +670,14 @@ class _HomeTVOSScreenState extends LasyRenderingState options.invalidServerError = tcontext.HomeScreen.invalidServer; options.expiredServerError = tcontext.HomeScreen.expiredServer; ReturnResultError? err = await VPNService.setServer(VPNService.getCurrent(), - options, SingboxExportType.tvos, widget.secret, savePath); + options, SingboxExportType.tvos, widget.host, widget.secret, savePath); if (err != null) { - if (!context.mounted) { + if (!mounted) { return; } - DialogUtils.showAlertDialog(context, err.message); + DialogUtils.showAlertDialog(context, err.message, + showCopy: true, showFAQ: true, withVersion: true); return; } try { @@ -688,11 +690,12 @@ class _HomeTVOSScreenState extends LasyRenderingState ReturnResult result = await HttpUtils.httpPostRequest(url, null, headers, content, const Duration(seconds: 5), null, null, null); - if (!context.mounted) { + if (!mounted) { return; } if (result.error != null) { - DialogUtils.showAlertDialog(context, result.error!.message); + DialogUtils.showAlertDialog(context, result.error!.message, + showCopy: true, showFAQ: true, withVersion: true); } else { if (result.data!.isNotEmpty) { DialogUtils.showAlertDialog(context, result.data!); @@ -701,10 +704,11 @@ class _HomeTVOSScreenState extends LasyRenderingState } } } catch (err) { - if (!context.mounted) { + if (!mounted) { return; } - DialogUtils.showAlertDialog(context, err.toString()); + DialogUtils.showAlertDialog(context, err.toString(), + showCopy: true, showFAQ: true, withVersion: true); } } @@ -715,7 +719,7 @@ class _HomeTVOSScreenState extends LasyRenderingState if (del != true) { return; } - if (!context.mounted) { + if (!mounted) { return; } @@ -725,11 +729,12 @@ class _HomeTVOSScreenState extends LasyRenderingState ReturnResult result = await HttpUtils.httpGetRequest( url, null, null, const Duration(seconds: 5), null, null); - if (!context.mounted) { + if (!mounted) { return; } if (result.error != null) { - DialogUtils.showAlertDialog(context, result.error!.message); + DialogUtils.showAlertDialog(context, result.error!.message, + showCopy: true, showFAQ: true, withVersion: true); } else { if (result.data!.isNotEmpty) { DialogUtils.showAlertDialog(context, result.data!); @@ -739,10 +744,11 @@ class _HomeTVOSScreenState extends LasyRenderingState } } } catch (err) { - if (!context.mounted) { + if (!mounted) { return; } - DialogUtils.showAlertDialog(context, err.toString()); + DialogUtils.showAlertDialog(context, err.toString(), + showCopy: true, showFAQ: true, withVersion: true); } } } diff --git a/lib/screens/language_settings_screen.dart b/lib/screens/language_settings_screen.dart index 6dc846d..db5231e 100644 --- a/lib/screens/language_settings_screen.dart +++ b/lib/screens/language_settings_screen.dart @@ -71,6 +71,7 @@ class _LanguageSettingsScreenState @override Widget build(BuildContext context) { final tcontext = Translations.of(context); + Size windowSize = MediaQuery.of(context).size; return Scaffold( appBar: PreferredSize( preferredSize: Size.zero, @@ -102,11 +103,16 @@ class _LanguageSettingsScreenState width: 50, height: 30, ), - Text( - tcontext.language, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2, + child: Text( + tcontext.language, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), widget.nextText != null ? SizedBox( @@ -240,14 +246,9 @@ class _LanguageSettingsScreenState void onTapItem(dynamic current) { SettingManager.getConfig().languageTag = current.languageTag; - - if (widget.nextText != null) { - LocaleSettings.setLocale(current); - } else { + LocaleSettings.setLocale(current); + if (widget.nextText == null) { Navigator.pop(context); - Future.delayed(const Duration(milliseconds: 300), () { - LocaleSettings.setLocale(current); - }); } } } diff --git a/lib/screens/launch_failed_screen.dart b/lib/screens/launch_failed_screen.dart index db18f88..6a0e3dd 100644 --- a/lib/screens/launch_failed_screen.dart +++ b/lib/screens/launch_failed_screen.dart @@ -14,7 +14,7 @@ enum StartFailedReason { invalidProfile(name: "invalidProfile"), invalidVersion(name: "invalidVersion"), systemVersionLow(name: "systemVersionLow"), - startFromUNC(name: "UNC"); + invalidInstallPath(name: "invalidInstallPath"); const StartFailedReason({required this.name}); final String name; @@ -91,8 +91,9 @@ class _LaunchFailedScreenState extends LasyRenderingState { error = tcontext.LaunchFailedScreen.invalidVersion; } else if (widget.startFailedReason == StartFailedReason.systemVersionLow) { error = tcontext.LaunchFailedScreen.systemVersionLow; - } else if (widget.startFailedReason == StartFailedReason.startFromUNC) { - error = tcontext.LaunchFailedScreen.startFromUNC; + } else if (widget.startFailedReason == + StartFailedReason.invalidInstallPath) { + error = tcontext.LaunchFailedScreen.invalidInstallPath; } else { error = tcontext.LaunchFailedScreen.invalidProcess; } diff --git a/lib/screens/list_add_screen.dart b/lib/screens/list_add_screen.dart index 8bbfdd3..f5cc7a7 100644 --- a/lib/screens/list_add_screen.dart +++ b/lib/screens/list_add_screen.dart @@ -14,12 +14,14 @@ class ListAddScreen extends LasyRenderingStatefulWidget { final List data; final String dialogTitle; final String dialogTextHit; + final Future Function()? onTapAdd; const ListAddScreen({ super.key, required this.title, required this.data, this.dialogTitle = "", this.dialogTextHit = "", + this.onTapAdd, }); @override @@ -41,6 +43,7 @@ class _ServerSelectSearchSettingsScreenState @override Widget build(BuildContext context) { + Size windowSize = MediaQuery.of(context).size; return Scaffold( appBar: PreferredSize( preferredSize: Size.zero, @@ -67,11 +70,16 @@ class _ServerSelectSearchSettingsScreenState ), ), ), - Text( - widget.title, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2, + child: Text( + widget.title, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), InkWell( onTap: () async { @@ -179,20 +187,26 @@ class _ServerSelectSearchSettingsScreenState } void onTapAdd() async { - final tcontext = Translations.of(context); - String? text = await DialogUtils.showTextInputDialog( - context, - widget.dialogTitle.isNotEmpty ? widget.dialogTitle : tcontext.add, - "", - widget.dialogTextHit.isNotEmpty ? widget.dialogTextHit : "", - null, (text) { - text = text.trim(); - if (text.isEmpty) { - return false; - } + String? text; + if (widget.onTapAdd != null) { + text = await widget.onTapAdd!(); + } else { + final tcontext = Translations.of(context); + text = await DialogUtils.showTextInputDialog( + context, + widget.dialogTitle.isNotEmpty ? widget.dialogTitle : tcontext.add, + "", + widget.dialogTextHit.isNotEmpty ? widget.dialogTextHit : "", + null, (text) { + text = text.trim(); + if (text.isEmpty) { + return false; + } + + return true; + }); + } - return true; - }); if (text == null) { return; } diff --git a/lib/screens/map_list_add_screen.dart b/lib/screens/map_string_and_list_add_screen.dart similarity index 88% rename from lib/screens/map_list_add_screen.dart rename to lib/screens/map_string_and_list_add_screen.dart index 67f21a1..c58a70f 100644 --- a/lib/screens/map_list_add_screen.dart +++ b/lib/screens/map_string_and_list_add_screen.dart @@ -7,9 +7,9 @@ import 'package:karing/screens/theme_define.dart'; import 'package:karing/screens/widgets/framework.dart'; import 'package:tuple/tuple.dart'; -class MapListAddScreen extends LasyRenderingStatefulWidget { +class MapStringAndListAddScreen extends LasyRenderingStatefulWidget { static RouteSettings routSettings() { - return const RouteSettings(name: "MapListAddScreen"); + return const RouteSettings(name: "MapStringAndListAddScreen"); } final String title; @@ -18,7 +18,7 @@ class MapListAddScreen extends LasyRenderingStatefulWidget { final String dialogTextHit1; final String dialogTitle2; final String dialogTextHit2; - const MapListAddScreen( + const MapStringAndListAddScreen( {super.key, required this.title, required this.data, @@ -28,12 +28,12 @@ class MapListAddScreen extends LasyRenderingStatefulWidget { this.dialogTextHit2 = ""}); @override - State createState() => + State createState() => _ServerSelectSearchSettingsScreenState(); } class _ServerSelectSearchSettingsScreenState - extends LasyRenderingState { + extends LasyRenderingState { @override void initState() { super.initState(); @@ -46,6 +46,7 @@ class _ServerSelectSearchSettingsScreenState @override Widget build(BuildContext context) { + Size windowSize = MediaQuery.of(context).size; return Scaffold( appBar: PreferredSize( preferredSize: Size.zero, @@ -72,11 +73,16 @@ class _ServerSelectSearchSettingsScreenState ), ), ), - Text( - widget.title, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2, + child: Text( + widget.title, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), InkWell( onTap: () async { diff --git a/lib/screens/map_string_and_string_add_screen.dart b/lib/screens/map_string_and_string_add_screen.dart new file mode 100644 index 0000000..987c07f --- /dev/null +++ b/lib/screens/map_string_and_string_add_screen.dart @@ -0,0 +1,245 @@ +import 'package:flutter/material.dart'; +import 'package:karing/i18n/strings.g.dart'; +import 'package:karing/screens/dialog_utils.dart'; +import 'package:karing/screens/theme_config.dart'; +import 'package:karing/screens/theme_define.dart'; +import 'package:karing/screens/widgets/framework.dart'; +import 'package:tuple/tuple.dart'; + +class MapStringAndStringAddScreen extends LasyRenderingStatefulWidget { + static RouteSettings routSettings() { + return const RouteSettings(name: "MapStringAndStringAddScreen"); + } + + final String title; + final List> data; + final String dialogTitle1; + final String dialogTextHit1; + final String dialogTitle2; + final String dialogTextHit2; + const MapStringAndStringAddScreen( + {super.key, + required this.title, + required this.data, + this.dialogTitle1 = "", + this.dialogTextHit1 = "", + this.dialogTitle2 = "", + this.dialogTextHit2 = ""}); + + @override + State createState() => + _ServerSelectSearchSettingsScreenState(); +} + +class _ServerSelectSearchSettingsScreenState + extends LasyRenderingState { + @override + void initState() { + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + @override + Widget build(BuildContext context) { + Size windowSize = MediaQuery.of(context).size; + return Scaffold( + appBar: PreferredSize( + preferredSize: Size.zero, + child: AppBar(), + ), + body: SafeArea( + child: Padding( + padding: const EdgeInsets.fromLTRB(0, 20, 0, 0), + child: Column( + children: [ + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + InkWell( + onTap: () => Navigator.pop(context), + child: const SizedBox( + width: 50, + height: 30, + child: Icon( + Icons.arrow_back_ios_outlined, + size: 26, + ), + ), + ), + SizedBox( + width: windowSize.width - 50 * 2, + child: Text( + widget.title, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), + ), + InkWell( + onTap: () async { + onTapAdd(); + }, + child: const SizedBox( + width: 50, + height: 30, + child: Icon( + Icons.add_outlined, + size: 26, + ), + ), + ) + ], + ), + ), + const SizedBox( + height: 10, + ), + Expanded( + child: _loadListView(), + ), + ], + ), + ), + ), + ); + } + + Widget _loadListView() { + Size windowSize = MediaQuery.of(context).size; + + return Scrollbar( + thumbVisibility: true, + child: ListView.builder( + itemCount: widget.data.length, + itemExtent: ThemeConfig.kListItemHeight2, + itemBuilder: (BuildContext context, int index) { + var current = widget.data[index]; + return createWidget(index, current, windowSize); + }, + )); + } + + Widget createWidget( + int index, Tuple2 current, Size windowSize) { + const double rightWidth = 30.0; + double centerWidth = windowSize.width - rightWidth - 20; + + return Container( + margin: const EdgeInsets.only(bottom: 2), + child: Material( + borderRadius: ThemeDefine.kBorderRadius, + child: InkWell( + onTap: () async { + onTapEditItem(current); + }, + child: Container( + padding: const EdgeInsets.symmetric( + horizontal: 10, + ), + width: double.infinity, + child: Row( + children: [ + Row( + children: [ + Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row(children: [ + SizedBox( + width: centerWidth, + child: Text( + current.item1, + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontSize: ThemeConfig.kFontSizeGroupItem, + ), + ), + ), + SizedBox( + width: rightWidth, + height: ThemeConfig.kListItemHeight2 - 2, + child: InkWell( + onTap: () async { + onTapDelete(index); + }, + child: const Icon( + Icons.remove_circle_outlined, + size: 26, + color: Colors.red, + ), + )) + ]), + ], + ), + ], + ), + ], + ), + ), + ), + ), + ); + } + + void onTapEditItem(Tuple2 current) async { + String? text = await DialogUtils.showTextInputDialog( + context, current.item1, current.item2, "", null, (text) { + text = text.trim(); + if (text.isEmpty) { + return false; + } + + return true; + }); + if (text == null || text.isEmpty) { + return; + } + for (var i = 0; i < widget.data.length; ++i) { + if (widget.data[i].item1 == current.item1) { + widget.data[i] = Tuple2(current.item1, text); + break; + } + } + + setState(() {}); + } + + void onTapAdd() async { + final tcontext = Translations.of(context); + String? text = await DialogUtils.showTextInputDialog( + context, tcontext.add, "", "", null, (text) { + text = text.trim(); + if (text.isEmpty) { + return false; + } + + return true; + }); + if (text == null || text.isEmpty) { + return; + } + for (var current in widget.data) { + if (current.item1 == text) { + return; + } + } + + widget.data.add(Tuple2(text, "")); + setState(() {}); + } + + void onTapDelete(int index) { + widget.data.removeAt(index); + + setState(() {}); + } +} diff --git a/lib/screens/multi_select_screen.dart b/lib/screens/multi_select_screen.dart index 1071a01..cff0fc5 100644 --- a/lib/screens/multi_select_screen.dart +++ b/lib/screens/multi_select_screen.dart @@ -79,6 +79,7 @@ class _MultiSelectScreenState extends LasyRenderingState { @override Widget build(BuildContext context) { final tcontext = Translations.of(context); + Size windowSize = MediaQuery.of(context).size; return Scaffold( appBar: PreferredSize( preferredSize: Size.zero, @@ -105,11 +106,16 @@ class _MultiSelectScreenState extends LasyRenderingState { ), ), ), - Text( - widget.title, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2, + child: Text( + widget.title, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), InkWell( onTap: () => Navigator.pop(context, widget.selectedData), diff --git a/lib/screens/my_profiles_edit_screen.dart b/lib/screens/my_profiles_edit_screen.dart index 630683e..93bc7bb 100644 --- a/lib/screens/my_profiles_edit_screen.dart +++ b/lib/screens/my_profiles_edit_screen.dart @@ -27,6 +27,7 @@ class _MyProfilesEditScreenState final _textControllerUrl = TextEditingController(); Duration? _updateTimeInterval = const Duration(hours: 12); String _compatible = ""; + ProxyFilter _proxyFilter = ProxyFilter(); bool _enableDiversionRules = false; bool _reloadAfterProfileUpdate = true; bool _testLatencyAfterProfileUpdate = false; @@ -45,6 +46,7 @@ class _MyProfilesEditScreenState ); _updateTimeInterval = item.updateDuration; _compatible = item.userAgentCompatible; + _proxyFilter = item.proxyFilter; _enableDiversionRules = item.enableDiversionRules; _reloadAfterProfileUpdate = item.reloadAfterProfileUpdate; _testLatencyAfterProfileUpdate = item.testLatencyAfterProfileUpdate; @@ -59,8 +61,9 @@ class _MyProfilesEditScreenState @override Widget build(BuildContext context) { - ServerConfigGroupItem? item = ServerManager.getByGroupId(widget.groupid); final tcontext = Translations.of(context); + Size windowSize = MediaQuery.of(context).size; + ServerConfigGroupItem? item = ServerManager.getByGroupId(widget.groupid); return Scaffold( appBar: PreferredSize( preferredSize: Size.zero, @@ -85,11 +88,16 @@ class _MyProfilesEditScreenState ), ), ), - Text( - tcontext.MyProfilesEditScreen.title, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2, + child: Text( + tcontext.MyProfilesEditScreen.title, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), InkWell( onTap: () { @@ -182,6 +190,8 @@ class _MyProfilesEditScreenState item.urlOrPath == urlText && item.updateDuration == _updateTimeInterval && item.userAgentCompatible == _compatible && + item.proxyFilter.method == _proxyFilter.method && + item.proxyFilter.keywordOrRegx == _proxyFilter.keywordOrRegx && item.enableDiversionRules == _enableDiversionRules && item.reloadAfterProfileUpdate == _reloadAfterProfileUpdate && item.testLatencyAfterProfileUpdate == _testLatencyAfterProfileUpdate && @@ -203,6 +213,7 @@ class _MyProfilesEditScreenState bool dirty = item.remark != remarkText; item.updateDuration = _updateTimeInterval; item.userAgentCompatible = _compatible; + item.proxyFilter = _proxyFilter; item.enableDiversionRules = _enableDiversionRules; item.reloadAfterProfileUpdate = _reloadAfterProfileUpdate; item.testLatencyAfterProfileUpdate = _testLatencyAfterProfileUpdate; @@ -267,6 +278,12 @@ class _MyProfilesEditScreenState onTapUserAgent(); })) : GroupItemOptions(), + GroupItemOptions( + pushOptions: GroupItemPushOptions( + name: tcontext.filter, + onPush: () async { + onTapFilter(); + })), GroupItemOptions( switchOptions: GroupItemSwitchOptions( name: tcontext.diversionRulesEnable, @@ -287,7 +304,7 @@ class _MyProfilesEditScreenState return; } if (duration != null && duration.inMinutes < 5) { - duration = const Duration(days: 365); + duration = const Duration(minutes: 5); } _updateTimeInterval = duration; setState(() {}); @@ -331,4 +348,9 @@ class _MyProfilesEditScreenState _compatible = await GroupHelper.showUserAgent(context, _compatible); setState(() {}); } + + void onTapFilter() async { + _proxyFilter = await GroupHelper.showProxyFilter(context, _proxyFilter); + setState(() {}); + } } diff --git a/lib/screens/my_profiles_merge_screen.dart b/lib/screens/my_profiles_merge_screen.dart index fb15523..913b00c 100644 --- a/lib/screens/my_profiles_merge_screen.dart +++ b/lib/screens/my_profiles_merge_screen.dart @@ -66,11 +66,16 @@ class MyProfilesMergeScreenState ), ), ), - Text( - tcontext.MyProfilesMergeScreen.profilesMerge, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2, + child: Text( + tcontext.MyProfilesMergeScreen.profilesMerge, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), _selectedSources.isNotEmpty ? InkWell( diff --git a/lib/screens/my_profiles_reorder_screen.dart b/lib/screens/my_profiles_reorder_screen.dart index 1af6002..64e675e 100644 --- a/lib/screens/my_profiles_reorder_screen.dart +++ b/lib/screens/my_profiles_reorder_screen.dart @@ -61,6 +61,7 @@ class MyProfilesReorderScreenState @override Widget build(BuildContext context) { final tcontext = Translations.of(context); + Size windowSize = MediaQuery.of(context).size; return Scaffold( appBar: PreferredSize( preferredSize: Size.zero, @@ -87,11 +88,16 @@ class MyProfilesReorderScreenState ), ), ), - Text( - tcontext.sort, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2, + child: Text( + tcontext.sort, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), const SizedBox( width: 50, diff --git a/lib/screens/my_profiles_screen.dart b/lib/screens/my_profiles_screen.dart index d2ba4f2..180b886 100644 --- a/lib/screens/my_profiles_screen.dart +++ b/lib/screens/my_profiles_screen.dart @@ -358,7 +358,7 @@ class MyProfilesScreenState extends LasyRenderingState { if (value != null) { DialogUtils.showAlertDialog( context, tcontext.updateFailed(p: value.message), - showCopy: true, withVersion: true); + showCopy: true, showFAQ: true, withVersion: true); } if (!mounted) { return; @@ -534,7 +534,7 @@ class MyProfilesScreenState extends LasyRenderingState { setState(() {}); DialogUtils.showAlertDialog(context, err.message, - showCopy: true, withVersion: true); + showCopy: true, showFAQ: true, withVersion: true); } } }); @@ -590,12 +590,13 @@ class MyProfilesScreenState extends LasyRenderingState { if (value != null) { DialogUtils.showAlertDialog( context, tcontext.updateFailed(p: value.message), - showCopy: true, withVersion: true); + showCopy: true, showFAQ: true, withVersion: true); } }); } else { DialogUtils.showAlertDialog( - context, tcontext.updateFailed(p: value.error!.message)); + context, tcontext.updateFailed(p: value.error!.message), + showCopy: true, showFAQ: true, withVersion: true); } } }, @@ -785,7 +786,10 @@ class MyProfilesScreenState extends LasyRenderingState { setState(() {}); DialogUtils.showAlertDialog( - context, err.message); + context, err.message, + showCopy: true, + showFAQ: true, + withVersion: true); } } }); @@ -809,6 +813,7 @@ class MyProfilesScreenState extends LasyRenderingState { @override Widget build(BuildContext context) { final tcontext = Translations.of(context); + Size windowSize = MediaQuery.of(context).size; return Scaffold( appBar: PreferredSize( preferredSize: Size.zero, @@ -846,11 +851,16 @@ class MyProfilesScreenState extends LasyRenderingState { : Icons.keyboard_double_arrow_down_outlined, size: 26, ), - Text( - tcontext.MyProfilesScreen.title, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 3 - 26, + child: Text( + tcontext.MyProfilesScreen.title, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), ]), ), @@ -1249,7 +1259,7 @@ class MyProfilesScreenState extends LasyRenderingState { SingboxOutboundType.hysteria2.name, SingboxOutboundType.wireguard.name, SingboxOutboundType.tuic.name, - //SingboxOutboundType.tor.name, + SingboxOutboundType.tor.name, SingboxOutboundType.ssh.name, ], SingboxOutboundType.socks.name, @@ -1296,6 +1306,9 @@ class MyProfilesScreenState extends LasyRenderingState { case "tuic": sbOptions.tuic = SingboxJsonOutboundTUICOptions(); break; + case "tor": + sbOptions.tor = SingboxJsonOutboundTorOptions(); + break; case "ssh": sbOptions.ssh = SingboxJsonOutboundSSHOptions(); break; @@ -1341,6 +1354,7 @@ class MyProfilesScreenState extends LasyRenderingState { if (!mounted) { return false; } + String? ret; ProxyConfig server = ProxyConfig(); server.groupid = item.groupid; server.index = item.servers.length; @@ -1348,70 +1362,97 @@ class MyProfilesScreenState extends LasyRenderingState { server.type = sbOptions.type; switch (sbOptions.type) { case "shadowsocks": + ret = sbOptions.shadowsocks!.getRequired(); sbOptions.server = sbOptions.shadowsocks!.server ?? ""; sbOptions.server_port = sbOptions.shadowsocks!.server_port ?? 0; break; case "shadowsocksr": + ret = sbOptions.shadowsocksr!.getRequired(); sbOptions.server = sbOptions.shadowsocksr!.server ?? ""; sbOptions.server_port = sbOptions.shadowsocksr!.server_port ?? 0; break; case "shadowtls": + ret = sbOptions.shadowtls!.getRequired(); sbOptions.server = sbOptions.shadowtls!.server ?? ""; sbOptions.server_port = sbOptions.shadowtls!.server_port ?? 0; break; case "vmess": + ret = sbOptions.vmess!.getRequired(); sbOptions.server = sbOptions.vmess!.server ?? ""; sbOptions.server_port = sbOptions.vmess!.server_port ?? 0; break; case "vless": + ret = sbOptions.vless!.getRequired(); sbOptions.server = sbOptions.vless!.server ?? ""; sbOptions.server_port = sbOptions.vless!.server_port ?? 0; break; case "trojan": + ret = sbOptions.trojan!.getRequired(); sbOptions.server = sbOptions.trojan!.server ?? ""; sbOptions.server_port = sbOptions.trojan!.server_port ?? 0; break; case "socks": + ret = sbOptions.socks!.getRequired(); sbOptions.server = sbOptions.socks!.server ?? ""; sbOptions.server_port = sbOptions.socks!.server_port ?? 0; break; case "http": + ret = sbOptions.http!.getRequired(); sbOptions.server = sbOptions.http!.server ?? ""; sbOptions.server_port = sbOptions.http!.server_port ?? 0; break; case "hysteria": + ret = sbOptions.hysteria!.getRequired(); sbOptions.server = sbOptions.hysteria!.server ?? ""; sbOptions.server_port = sbOptions.hysteria!.server_port ?? 0; break; case "hysteria2": + ret = sbOptions.hysteria2!.getRequired(); sbOptions.server = sbOptions.hysteria2!.server ?? ""; sbOptions.server_port = sbOptions.hysteria2!.server_port ?? 0; break; case "wireguard": + ret = sbOptions.wg!.getRequired(); sbOptions.server = sbOptions.wg!.server ?? ""; sbOptions.server_port = sbOptions.wg!.server_port ?? 0; break; case "tuic": + ret = sbOptions.tuic!.getRequired(); sbOptions.server = sbOptions.tuic!.server ?? ""; sbOptions.server_port = sbOptions.tuic!.server_port ?? 0; break; + case "tor": + ret = sbOptions.tor!.getRequired(); + sbOptions.server = sbOptions.tor!.server ?? ""; + sbOptions.server_port = sbOptions.tor!.server_port ?? 0; + break; case "ssh": + ret = sbOptions.ssh!.getRequired(); sbOptions.server = sbOptions.ssh!.server ?? ""; sbOptions.server_port = sbOptions.ssh!.server_port ?? 0; break; } - + if (ret != null) { + DialogUtils.showAlertDialog( + context, "$ret ${tcontext.required}"); + return false; + } + if (sbOptions.tag.isEmpty) { + DialogUtils.showAlertDialog( + context, "tag ${tcontext.required}"); + return false; + } server.server = sbOptions.server; server.serverport = sbOptions.server_port; server.raw = sbOptions.toJson(); @@ -1454,7 +1495,7 @@ class MyProfilesScreenState extends LasyRenderingState { config.dns = SingboxConfigBuilder.dns(false, SingboxExportType.singbox, null); config.inbounds = SingboxConfigBuilder.inbounds( - false, false, [], SingboxExportType.singbox); + false, false, [], SingboxExportType.singbox, null); for (var inbound in config.inbounds) { if (inbound is SingboxInboundTunOptions) { inbound.inet4_address = ["172.19.0.1/30"]; @@ -1471,7 +1512,7 @@ class MyProfilesScreenState extends LasyRenderingState { allOutBounds, null, {}, - "", + [], SingboxExportType.singbox); var sitecodes = await RulesetCodesUtils.siteCodes(); diff --git a/lib/screens/net_check_screen.dart b/lib/screens/net_check_screen.dart index 45464e7..66c7ad8 100644 --- a/lib/screens/net_check_screen.dart +++ b/lib/screens/net_check_screen.dart @@ -15,7 +15,6 @@ import 'package:karing/app/utils/network_utils.dart'; import 'package:karing/app/utils/proxy_conf_utils.dart'; import 'package:karing/app/utils/singbox_config_builder.dart'; import 'package:karing/i18n/strings.g.dart'; -import 'package:karing/screens/common_dialog.dart'; import 'package:karing/screens/dialog_utils.dart'; import 'package:karing/screens/listview_multi_parts_builder.dart'; import 'package:karing/screens/theme_config.dart'; @@ -648,7 +647,7 @@ class _NetCheckScreenState extends LasyRenderingState { if (_domainAndPort.item2 == null) { result = await HttpUtils.httpGetRequest( "https://${_domainAndPort.item1}", - settingConfig.proxy.mixedPort, + settingConfig.proxy.mixedRulePort, null, timeout, null, @@ -660,7 +659,7 @@ class _NetCheckScreenState extends LasyRenderingState { if (result.error != null) { result = await HttpUtils.httpGetRequest( "http://${_domainAndPort.item1}", - settingConfig.proxy.mixedPort, + settingConfig.proxy.mixedRulePort, null, timeout, null, @@ -670,7 +669,7 @@ class _NetCheckScreenState extends LasyRenderingState { } else { result = await HttpUtils.httpGetRequest( "https://${_domainAndPort.item1}:${_domainAndPort.item2}", - settingConfig.proxy.mixedPort, + settingConfig.proxy.mixedRulePort, null, timeout, null, @@ -682,7 +681,7 @@ class _NetCheckScreenState extends LasyRenderingState { if (result.error != null) { result = await HttpUtils.httpGetRequest( "http://${_domainAndPort.item1}:${_domainAndPort.item2}", - settingConfig.proxy.mixedPort, + settingConfig.proxy.mixedRulePort, null, timeout, null, @@ -717,6 +716,7 @@ class _NetCheckScreenState extends LasyRenderingState { @override Widget build(BuildContext context) { final tcontext = Translations.of(context); + Size windowSize = MediaQuery.of(context).size; return Scaffold( appBar: PreferredSize( preferredSize: Size.zero, @@ -741,11 +741,16 @@ class _NetCheckScreenState extends LasyRenderingState { ), ), ), - Text( - tcontext.NetCheckScreen.title, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 3 - 26, + child: Text( + tcontext.NetCheckScreen.title, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), const SizedBox( width: 50, diff --git a/lib/screens/net_connections_filter_screen.dart b/lib/screens/net_connections_filter_screen.dart index 6ba6b2e..25a095c 100644 --- a/lib/screens/net_connections_filter_screen.dart +++ b/lib/screens/net_connections_filter_screen.dart @@ -53,6 +53,7 @@ class _NetConnectionsFilterScreenState @override Widget build(BuildContext context) { final tcontext = Translations.of(context); + Size windowSize = MediaQuery.of(context).size; return Scaffold( appBar: PreferredSize( preferredSize: Size.zero, @@ -79,11 +80,16 @@ class _NetConnectionsFilterScreenState ), ), ), - Text( - tcontext.NetConnectionsFilterScreen.title, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 3, + child: Text( + tcontext.NetConnectionsFilterScreen.title, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), Row( children: [ diff --git a/lib/screens/net_connections_screen.dart b/lib/screens/net_connections_screen.dart index cf29526..191f59e 100644 --- a/lib/screens/net_connections_screen.dart +++ b/lib/screens/net_connections_screen.dart @@ -440,6 +440,7 @@ class _NetConnectionsScreenState @override Widget build(BuildContext context) { final tcontext = Translations.of(context); + Size windowSize = MediaQuery.of(context).size; return PopScope( canPop: true, onPopInvokedWithResult: (didPop, result) { @@ -471,11 +472,16 @@ class _NetConnectionsScreenState ), ), ), - Text( - tcontext.NetConnectionsScreen.title, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2, + child: Text( + tcontext.NetConnectionsScreen.title, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), InkWell( onTap: () async { diff --git a/lib/screens/net_interfaces_screen.dart b/lib/screens/net_interfaces_screen.dart index 15fb0cb..543ac1b 100644 --- a/lib/screens/net_interfaces_screen.dart +++ b/lib/screens/net_interfaces_screen.dart @@ -33,6 +33,7 @@ class _NetInterfacesScreenState @override Widget build(BuildContext context) { final tcontext = Translations.of(context); + Size windowSize = MediaQuery.of(context).size; return Scaffold( appBar: PreferredSize( preferredSize: Size.zero, @@ -59,11 +60,16 @@ class _NetInterfacesScreenState ), ), ), - Text( - tcontext.netInterfaces, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2, + child: Text( + tcontext.netInterfaces, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), const SizedBox( width: 50, diff --git a/lib/screens/novice_screen.dart b/lib/screens/novice_screen.dart index 86a0c96..6191399 100644 --- a/lib/screens/novice_screen.dart +++ b/lib/screens/novice_screen.dart @@ -29,7 +29,7 @@ class _NoviceScreenState extends LasyRenderingState { @override Widget build(BuildContext context) { final tcontext = Translations.of(context); - + Size windowSize = MediaQuery.of(context).size; return Scaffold( appBar: PreferredSize( preferredSize: Size.zero, @@ -51,11 +51,16 @@ class _NoviceScreenState extends LasyRenderingState { const SizedBox( width: 50, ), - Text( - tcontext.setting, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2, + child: Text( + tcontext.setting, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), SizedBox( width: 65, diff --git a/lib/screens/perapp_android_screen.dart b/lib/screens/perapp_android_screen.dart index 5c25bfc..00052b2 100644 --- a/lib/screens/perapp_android_screen.dart +++ b/lib/screens/perapp_android_screen.dart @@ -227,6 +227,7 @@ class _PerAppAndroidScreenState @override Widget build(BuildContext context) { final tcontext = Translations.of(context); + Size windowSize = MediaQuery.of(context).size; return Scaffold( appBar: PreferredSize( preferredSize: Size.zero, @@ -253,11 +254,16 @@ class _PerAppAndroidScreenState ), ), ), - Text( - tcontext.PerAppAndroidScreen.title, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2, + child: Text( + tcontext.PerAppAndroidScreen.title, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), InkWell( onTap: () async { @@ -556,7 +562,8 @@ class _PerAppAndroidScreenState if (!mounted) { return; } - DialogUtils.showAlertDialog(context, err.toString()); + DialogUtils.showAlertDialog(context, err.toString(), + showCopy: true, showFAQ: true, withVersion: true); } }), PopupMenuItem( @@ -585,7 +592,8 @@ class _PerAppAndroidScreenState if (!mounted) { return; } - DialogUtils.showAlertDialog(context, err.toString()); + DialogUtils.showAlertDialog(context, err.toString(), + showCopy: true, showFAQ: true, withVersion: true); } }, ), diff --git a/lib/screens/qrcode_scan_screen.dart b/lib/screens/qrcode_scan_screen.dart index 0b103b4..f2fa321 100644 --- a/lib/screens/qrcode_scan_screen.dart +++ b/lib/screens/qrcode_scan_screen.dart @@ -76,11 +76,16 @@ class _QrcodeScanScreenState extends LasyRenderingState { ), ), ), - Text( - tcontext.scanQrcode, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2, + child: Text( + tcontext.scanQrcode, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), SizedBox( width: 50, @@ -100,7 +105,8 @@ class _QrcodeScanScreenState extends LasyRenderingState { try { await controller!.toggleFlash(); } catch (err) { - DialogUtils.showAlertDialog(context, err.toString()); + DialogUtils.showAlertDialog(context, err.toString(), + showCopy: true, showFAQ: true, withVersion: true); } setState(() {}); diff --git a/lib/screens/qrcode_screen.dart b/lib/screens/qrcode_screen.dart index c7f0503..cf35b33 100644 --- a/lib/screens/qrcode_screen.dart +++ b/lib/screens/qrcode_screen.dart @@ -88,11 +88,16 @@ class _QrcodeScreenState extends LasyRenderingState { ), ), ), - Text( - tcontext.qrcode, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2, + child: Text( + tcontext.qrcode, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), const SizedBox( width: 50, diff --git a/lib/screens/region_settings_screen.dart b/lib/screens/region_settings_screen.dart index 3e38a43..a327f73 100644 --- a/lib/screens/region_settings_screen.dart +++ b/lib/screens/region_settings_screen.dart @@ -131,6 +131,7 @@ class _RegionSetingsScreenState @override Widget build(BuildContext context) { final tcontext = Translations.of(context); + Size windowSize = MediaQuery.of(context).size; return Scaffold( appBar: PreferredSize( preferredSize: Size.zero, @@ -162,11 +163,16 @@ class _RegionSetingsScreenState width: 50, height: 30, ), - Text( - tcontext.RegionSettingsScreen.title, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2, + child: Text( + tcontext.RegionSettingsScreen.title, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), widget.nextText != null ? SizedBox( diff --git a/lib/screens/richtext_viewer.screen.dart b/lib/screens/richtext_viewer.screen.dart index 911942b..5c620ad 100644 --- a/lib/screens/richtext_viewer.screen.dart +++ b/lib/screens/richtext_viewer.screen.dart @@ -48,6 +48,7 @@ class _RichtextViewScreenState extends LasyRenderingState { @override Widget build(BuildContext context) { + Size windowSize = MediaQuery.of(context).size; return Scaffold( appBar: PreferredSize( preferredSize: Size.zero, @@ -72,11 +73,16 @@ class _RichtextViewScreenState extends LasyRenderingState { ), ), ), - Text( - widget.title, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2, + child: Text( + widget.title, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), widget.content.isNotEmpty ? InkWell( diff --git a/lib/screens/server_select_keywords_screen.dart b/lib/screens/server_select_keywords_screen.dart index d5fe697..9885e63 100644 --- a/lib/screens/server_select_keywords_screen.dart +++ b/lib/screens/server_select_keywords_screen.dart @@ -42,6 +42,7 @@ class _ServerSelectSearchSettingsScreenState @override Widget build(BuildContext context) { final tcontext = Translations.of(context); + Size windowSize = MediaQuery.of(context).size; return Scaffold( appBar: PreferredSize( preferredSize: Size.zero, @@ -68,11 +69,16 @@ class _ServerSelectSearchSettingsScreenState ), ), ), - Text( - tcontext.candidateWord, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2, + child: Text( + tcontext.candidateWord, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), InkWell( onTap: () async { @@ -186,7 +192,7 @@ class _ServerSelectSearchSettingsScreenState void onTapAdd() async { final tcontext = Translations.of(context); String? text = await DialogUtils.showTextInputDialog( - context, tcontext.keywordsOrRegx, "", null, null, (text) { + context, tcontext.keywordOrRegx, "", null, null, (text) { text = text.trim(); if (text.isEmpty) { return false; @@ -229,7 +235,7 @@ class _ServerSelectSearchSettingsScreenState void onLongPressEdit(int index, String text) async { final tcontext = Translations.of(context); String? newText = await DialogUtils.showTextInputDialog( - context, tcontext.keywordsOrRegx, text, null, null, (text) { + context, tcontext.keywordOrRegx, text, null, null, (text) { text = text.trim(); if (text.isEmpty) { return false; diff --git a/lib/screens/server_select_screen.dart b/lib/screens/server_select_screen.dart index 5af41fe..bec0681 100644 --- a/lib/screens/server_select_screen.dart +++ b/lib/screens/server_select_screen.dart @@ -804,7 +804,7 @@ class _ServerSelectScreenState extends LasyRenderingState { if (value != null) { DialogUtils.showAlertDialog( context, tcontext.updateFailed(p: value.message), - showCopy: true, withVersion: true); + showCopy: true, showFAQ: true, withVersion: true); } if (!mounted) { return; @@ -874,7 +874,10 @@ class _ServerSelectScreenState extends LasyRenderingState { if (mounted) { setState(() {}); - DialogUtils.showAlertDialog(context, err.message); + DialogUtils.showAlertDialog(context, err.message, + showCopy: true, + showFAQ: true, + withVersion: true); } } }); @@ -931,12 +934,15 @@ class _ServerSelectScreenState extends LasyRenderingState { if (value != null) { DialogUtils.showAlertDialog(context, tcontext.updateFailed(p: value.message), - showCopy: true, withVersion: true); + showCopy: true, + showFAQ: true, + withVersion: true); } }); } else { DialogUtils.showAlertDialog(context, - tcontext.updateFailed(p: value.error!.message)); + tcontext.updateFailed(p: value.error!.message), + showCopy: true, showFAQ: true, withVersion: true); } } @@ -1264,7 +1270,10 @@ class _ServerSelectScreenState extends LasyRenderingState { setState(() {}); DialogUtils.showAlertDialog( - context, err.message); + context, err.message, + showCopy: true, + showFAQ: true, + withVersion: true); } } }); @@ -1407,6 +1416,7 @@ class _ServerSelectScreenState extends LasyRenderingState { @override Widget build(BuildContext context) { final tcontext = Translations.of(context); + Size windowSize = MediaQuery.of(context).size; return Scaffold( appBar: PreferredSize( preferredSize: Size.zero, @@ -1453,13 +1463,18 @@ class _ServerSelectScreenState extends LasyRenderingState { : Icons.keyboard_double_arrow_down_outlined, size: 26, ), - Text( - widget.title != null && widget.title!.isNotEmpty - ? widget.title! - : tcontext.ServerSelectScreen.title, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 3 - 26, + child: Text( + widget.title != null && widget.title!.isNotEmpty + ? widget.title! + : tcontext.ServerSelectScreen.title, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), ]), ), diff --git a/lib/screens/settings_screen.dart b/lib/screens/settings_screen.dart index 408676d..1ee73d6 100644 --- a/lib/screens/settings_screen.dart +++ b/lib/screens/settings_screen.dart @@ -11,20 +11,21 @@ import 'package:karing/app/local_services/vpn_service.dart'; import 'package:karing/app/modules/auto_update_manager.dart'; import 'package:karing/app/modules/biz.dart'; import 'package:karing/app/modules/notice_manager.dart'; -import 'package:karing/app/modules/proxy_cluster.dart'; import 'package:karing/app/modules/remote_config_manager.dart'; import 'package:karing/app/modules/remote_isp_config_manager.dart'; import 'package:karing/app/modules/server_manager.dart'; import 'package:karing/app/modules/setting_manager.dart'; +import 'package:karing/app/private/ads_banner_widget_private.dart'; +import 'package:karing/app/private/ads_private.dart'; import 'package:karing/app/runtime/return_result.dart'; import 'package:karing/app/utils/analytics_utils.dart'; import 'package:karing/app/utils/apple_utils.dart'; import 'package:karing/app/utils/clash_api.dart'; import 'package:karing/app/utils/cloudflare_warp_api.dart'; import 'package:karing/app/utils/file_utils.dart'; -import 'package:karing/app/utils/google_admob.dart'; import 'package:karing/app/utils/install_referrer_utils.dart'; import 'package:karing/app/utils/karing_url_utils.dart'; +import 'package:karing/app/utils/network_utils.dart'; import 'package:karing/app/utils/path_utils.dart'; import 'package:karing/app/utils/platform_utils.dart'; import 'package:karing/app/utils/proxy_conf_utils.dart'; @@ -45,16 +46,17 @@ import 'package:karing/screens/net_interfaces_screen.dart'; import 'package:karing/screens/perapp_android_screen.dart'; import 'package:karing/screens/qrcode_screen.dart'; import 'package:karing/screens/richtext_viewer.screen.dart'; -import 'package:karing/screens/server_select_screen.dart'; import 'package:karing/screens/speedtest_settings_screen.dart'; import 'package:karing/screens/text_to_qrcode_screen.dart'; import 'package:karing/screens/theme_config.dart'; import 'package:karing/screens/urltest_settings_screen.dart'; +import 'package:karing/screens/uwp_loopback_exemption_windows_screen.dart'; import 'package:karing/screens/version_update_screen.dart'; import 'package:karing/screens/widgets/framework.dart'; import 'package:path/path.dart' as path; import 'package:tuple/tuple.dart'; import 'package:url_launcher/url_launcher.dart'; +import 'package:vpn_service/vpn_service.dart'; class SettingsScreen extends LasyRenderingStatefulWidget { static RouteSettings routSettings() { @@ -108,6 +110,7 @@ class _SettingScreenState extends LasyRenderingState { @override Widget build(BuildContext context) { final tcontext = Translations.of(context); + Size windowSize = MediaQuery.of(context).size; return Scaffold( appBar: PreferredSize( preferredSize: Size.zero, @@ -134,11 +137,16 @@ class _SettingScreenState extends LasyRenderingState { ), ), ), - Text( - tcontext.setting, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2, + child: Text( + tcontext.setting, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), const SizedBox( width: 50, @@ -157,9 +165,21 @@ class _SettingScreenState extends LasyRenderingState { AsyncSnapshot> snapshot) { List data = snapshot.hasData ? snapshot.data! : []; - return Column( - children: - GroupItemCreator.createGroups(context, data)); + List children = []; + if (AdsPrivate.getEnable()) { + var settingConfig = SettingManager.getConfig(); + var expire = DateTime.tryParse( + settingConfig.ads.bannerRewardExpire); + if (expire == null || DateTime.now().isAfter(expire)) { + children.add(AdsBannerWidget( + adWidth: windowSize.width, + bannerName: "banner2")); + children.add(const SizedBox(height: 20)); + } + } + children + .addAll(GroupItemCreator.createGroups(context, data)); + return Column(children: children); }, ), ), @@ -180,7 +200,7 @@ class _SettingScreenState extends LasyRenderingState { } DialogUtils.showAlertDialog( context, "${err.toString()}\n${stacktrace.toString()}", - showCopy: true, withVersion: true); + showCopy: true, showFAQ: true, withVersion: true); return []; } } @@ -313,15 +333,6 @@ class _SettingScreenState extends LasyRenderingState { : GroupItemOptions(), ])); - /*if (GoogleAdmob.getEnable()) { - groupOptions.add(GroupItem(options: [ - GroupItemOptions( - pushOptions: GroupItemPushOptions( - name: tcontext.SettingsScreen.howToRemoveAds, - onPush: () async {})), - ])); - }*/ - if (!settingConfig.novice) { groupOptions.add(GroupItem(options: [ (PlatformUtils.isPC() || Platform.isAndroid) && @@ -364,6 +375,20 @@ class _SettingScreenState extends LasyRenderingState { settings: TextToQrCodeScreen.routSettings(), builder: (context) => const TextToQrCodeScreen())); })), + Platform.isWindows + ? GroupItemOptions( + pushOptions: GroupItemPushOptions( + name: tcontext.uwpExemption, + onPush: () async { + Navigator.push( + context, + MaterialPageRoute( + settings: UWPLoopbackExemptionWindowsScreen + .routSettings(), + builder: (context) => + const UWPLoopbackExemptionWindowsScreen())); + })) + : GroupItemOptions(), ])); groupOptions.add(GroupItem(options: [ GroupItemOptions( @@ -382,16 +407,10 @@ class _SettingScreenState extends LasyRenderingState { })), GroupItemOptions( pushOptions: GroupItemPushOptions( - name: tcontext.UrlTestSettingsScreen.title, - text: settingConfig.urlTest, + name: tcontext.latencyTest, textWidthPercent: 0.4, onPush: () async { - await Navigator.push( - context, - MaterialPageRoute( - settings: UrlTestSettingsScreen.routSettings(), - builder: (context) => const UrlTestSettingsScreen())); - setState(() {}); + onTapLatencyTest(); })), ])); } @@ -554,14 +573,6 @@ class _SettingScreenState extends LasyRenderingState { } if (!settingConfig.novice) { - String frontProxy = settingConfig.frontProxy; - if (settingConfig.frontProxy.isNotEmpty) { - ProxyConfig? currentServer = - ServerManager.getConfig().getByTag(settingConfig.frontProxy); - if (currentServer == null) { - frontProxy = ""; - } - } groupOptions.add(GroupItem(options: [ GroupItemOptions( pushOptions: GroupItemPushOptions( @@ -570,47 +581,6 @@ class _SettingScreenState extends LasyRenderingState { await onTapNetShare(); }, )), - GroupItemOptions( - pushOptions: GroupItemPushOptions( - name: tcontext.SettingsScreen.frontProxy, - tips: tcontext.SettingsScreen.frontProxyTips, - text: frontProxy, - style: TextStyle( - fontFamily: Platform.isWindows ? 'Emoji' : null, - ), - onPush: () async { - ProxyConfig? currentServer = - settingConfig.frontProxy.isNotEmpty - ? ServerManager.getConfig() - .getByTag(settingConfig.frontProxy) - : ProxyConfig(); - ProxyConfig? result = await Navigator.push( - context, - MaterialPageRoute( - settings: ServerSelectScreen.routSettings(), - builder: (context) => ServerSelectScreen( - singleSelect: - ServerSelectScreenSingleSelectedOption( - selectedServer: - currentServer ?? ProxyConfig(), - showNone: true, - showAutoSelect: false, - showUrltestGroup: false, - showFav: false, - showRecommend: false, - showRecent: false, - showTranffic: false, - showUpdate: false, - ), - multiSelect: null, - ))); - if (result != null && - result.tag != settingConfig.frontProxy) { - settingConfig.frontProxy = result.tag; - ServerManager.setDirty(true); - setState(() {}); - } - })), ])); } groupOptions.add(GroupItem(options: [ @@ -685,7 +655,8 @@ class _SettingScreenState extends LasyRenderingState { onSwitch: (bool value) async { ReturnResultError? err = await VPNService.setLaunchAtStartup(value); if (err != null) { - DialogUtils.showAlertDialog(context, err.message); + DialogUtils.showAlertDialog(context, err.message, + showCopy: true, showFAQ: true, withVersion: true); } setState(() {}); }, @@ -723,23 +694,22 @@ class _SettingScreenState extends LasyRenderingState { } ////////////////////// - if (Platform.isIOS /*|| Platform.isAndroid */ || Platform.isMacOS) { - //android不支持删除 + if (Platform.isIOS || Platform.isMacOS /*|| Platform.isAndroid */) { groupOptions.add(GroupItem(options: [ (Platform.isIOS || Platform.isMacOS) ? GroupItemOptions( - pushOptions: GroupItemPushOptions( - name: tcontext.SettingsScreen.removeSystemVPNConfig, - onPush: () async { - bool? del = await DialogUtils.showConfirmDialog( - context, tcontext.removeConfirm); - if (del == true) { - ReturnResultError? err = await VPNService.uninstall(); - if (err != null) { - DialogUtils.showAlertDialog(context, err.message); - } - } - })) + switchOptions: GroupItemSwitchOptions( + name: tcontext.SettingsScreen.alwayOnVPN, + switchValue: settingConfig.alwayOn, + onSwitch: (bool value) async { + settingConfig.alwayOn = value; + if (!value) { + FlutterVpnService.setAlwaysOn(value); + } + SettingManager.setDirty(true); + setState(() {}); + }, + )) : GroupItemOptions(), /*(Platform.isIOS || Platform.isAndroid) ? GroupItemOptions( @@ -751,6 +721,25 @@ class _SettingScreenState extends LasyRenderingState { })) : GroupItemOptions(),*/ ])); + //android不支持删除 + if (Platform.isIOS || Platform.isMacOS) { + groupOptions.add(GroupItem(options: [ + GroupItemOptions( + pushOptions: GroupItemPushOptions( + name: tcontext.SettingsScreen.removeSystemVPNConfig, + onPush: () async { + bool? del = await DialogUtils.showConfirmDialog( + context, tcontext.removeConfirm); + if (del == true) { + ReturnResultError? err = await VPNService.uninstall(); + if (err != null) { + DialogUtils.showAlertDialog(context, err.message, + showCopy: true, showFAQ: true, withVersion: true); + } + } + })), + ])); + } } //语言设置 groupOptions.add( @@ -918,7 +907,38 @@ class _SettingScreenState extends LasyRenderingState { : GroupItemOptions(), ])); } + if (AdsPrivate.getEnable()) { + groupOptions.add(GroupItem(options: [ + GroupItemOptions( + pushOptions: GroupItemPushOptions( + name: tcontext.removeBannerAds, + onPush: () async { + AnalyticsUtils.logEvent( + analyticsEventType: analyticsEventTypeUA, + name: 'adsReward'); + bool? ok = await DialogUtils.showConfirmDialog( + context, tcontext.removeBannerAdsByReward); + if (ok == true) { + DialogUtils.showLoadingDialog(context, text: ""); + AdsRewardWidget.loadGoogleRewardedAd((AdsRewardError? err) { + Navigator.pop(context); + if (err == null) { + settingConfig.ads.bannerRewardExpire = DateTime.now() + .add(const Duration(days: 7)) + .toString(); + setState(() {}); + DialogUtils.showAlertDialog( + context, tcontext.removeBannerAdsByRewardDone); + } else { + DialogUtils.showAlertDialog(context, err.toString(), + showCopy: true, showFAQ: true, withVersion: true); + } + }); + } + })) + ])); + } String? rateUrl = AppleUtils.getRateUrl(); //其他设置 groupOptions.add(GroupItem(options: [ @@ -1154,6 +1174,48 @@ class _SettingScreenState extends LasyRenderingState { setState(() {}); } + Future onTapLatencyTest() async { + final tcontext = Translations.of(context); + Future> getOptions(BuildContext context) async { + var settingConfig = SettingManager.getConfig(); + List options = [ + GroupItemOptions( + pushOptions: GroupItemPushOptions( + name: tcontext.url, + text: settingConfig.urlTest, + textWidthPercent: 0.4, + onPush: () async { + await Navigator.push( + context, + MaterialPageRoute( + settings: UrlTestSettingsScreen.routSettings(), + builder: (context) => const UrlTestSettingsScreen())); + setState(() {}); + })), + GroupItemOptions( + switchOptions: GroupItemSwitchOptions( + name: tcontext.latencyTestResolveIP, + switchValue: settingConfig.latencyCheckResoveIP, + onSwitch: (bool value) async { + settingConfig.latencyCheckResoveIP = value; + setState(() {}); + }, + )), + ]; + return [GroupItem(options: options)]; + } + + await Navigator.push( + context, + MaterialPageRoute( + settings: GroupScreen.routSettings("latencyTest"), + builder: (context) => GroupScreen( + title: tcontext.latencyTest, + getOptions: getOptions, + ))); + setState(() {}); + } + Future onTapPort() async { final tcontext = Translations.of(context); const int minPort = 2048; @@ -1164,16 +1226,29 @@ class _SettingScreenState extends LasyRenderingState { GroupItemOptions( pushOptions: GroupItemPushOptions( name: tcontext.SettingsScreen.portSettingRule, - text: settingConfig.proxy.mixedPort.toString(), + text: settingConfig.proxy.mixedRulePort.toString(), onPush: () async { int? p = await DialogUtils.showIntInputDialog( context, tcontext.SettingsScreen.modifyPort, - settingConfig.proxy.mixedPort, + settingConfig.proxy.mixedRulePort, minPort, maxPort); + if (p != null) { - settingConfig.proxy.mixedPort = p; + List ports = [ + //settingConfig.proxy.mixedRulePort, + settingConfig.proxy.mixedDirectPort, + settingConfig.proxy.mixedForwordPort, + settingConfig.proxy.controlPort, + settingConfig.proxy.clusterPort, + ]; + if (ports.contains(p)) { + await DialogUtils.showAlertDialog( + context, tcontext.SettingsScreen.modifyPortOccupied); + return; + } + settingConfig.proxy.mixedRulePort = p; SettingManager.setDirty(true); setState(() {}); } @@ -1190,6 +1265,18 @@ class _SettingScreenState extends LasyRenderingState { minPort, maxPort); if (p != null) { + List ports = [ + settingConfig.proxy.mixedRulePort, + //settingConfig.proxy.mixedDirectPort, + settingConfig.proxy.mixedForwordPort, + settingConfig.proxy.controlPort, + settingConfig.proxy.clusterPort, + ]; + if (ports.contains(p)) { + await DialogUtils.showAlertDialog( + context, tcontext.SettingsScreen.modifyPortOccupied); + return; + } settingConfig.proxy.mixedDirectPort = p; SettingManager.setDirty(true); setState(() {}); @@ -1207,6 +1294,18 @@ class _SettingScreenState extends LasyRenderingState { minPort, maxPort); if (p != null) { + List ports = [ + settingConfig.proxy.mixedRulePort, + settingConfig.proxy.mixedDirectPort, + //settingConfig.proxy.mixedForwordPort, + settingConfig.proxy.controlPort, + settingConfig.proxy.clusterPort, + ]; + if (ports.contains(p)) { + await DialogUtils.showAlertDialog( + context, tcontext.SettingsScreen.modifyPortOccupied); + return; + } settingConfig.proxy.mixedForwordPort = p; SettingManager.setDirty(true); setState(() {}); @@ -1224,6 +1323,18 @@ class _SettingScreenState extends LasyRenderingState { minPort, maxPort); if (p != null) { + List ports = [ + settingConfig.proxy.mixedRulePort, + settingConfig.proxy.mixedDirectPort, + settingConfig.proxy.mixedForwordPort, + //settingConfig.proxy.controlPort, + settingConfig.proxy.clusterPort, + ]; + if (ports.contains(p)) { + await DialogUtils.showAlertDialog( + context, tcontext.SettingsScreen.modifyPortOccupied); + return; + } settingConfig.proxy.controlPort = p; SettingManager.setDirty(true); setState(() {}); @@ -1242,6 +1353,18 @@ class _SettingScreenState extends LasyRenderingState { minPort, maxPort); if (p != null) { + List ports = [ + settingConfig.proxy.mixedRulePort, + settingConfig.proxy.mixedDirectPort, + settingConfig.proxy.mixedForwordPort, + settingConfig.proxy.controlPort, + //settingConfig.proxy.clusterPort, + ]; + if (ports.contains(p)) { + await DialogUtils.showAlertDialog(context, + tcontext.SettingsScreen.modifyPortOccupied); + return; + } settingConfig.proxy.clusterPort = p; SettingManager.setDirty(true); setState(() {}); @@ -1924,6 +2047,23 @@ class _SettingScreenState extends LasyRenderingState { final tcontext = Translations.of(context); Future> getOptions(BuildContext context) async { var settingConfig = SettingManager.getConfig(); + + String ipLocal = "127.0.0.1"; + String ipInterface = ipLocal; + if (settingConfig.proxy.getAllowAllInbounds() || + settingConfig.proxy.getClusterAllowAllInbounds()) { + List interfaces = await NetworkUtils.getInterfaces( + addressType: InternetAddressType.IPv4); + if (interfaces.isNotEmpty) { + ipInterface = interfaces.first.address; + } + for (var interf in interfaces) { + if (interf.name.startsWith("en") || interf.name.startsWith("wlan")) { + ipInterface = interf.address; + break; + } + } + } List options = [ GroupItemOptions( pushOptions: GroupItemPushOptions( @@ -1942,11 +2082,15 @@ class _SettingScreenState extends LasyRenderingState { switchOptions: GroupItemSwitchOptions( name: tcontext.SettingsScreen.allowOtherHostsConnect, // ignore: prefer_interpolation_to_compose_strings - tips: tcontext.SettingsScreen.portSettingRule + + tips: (settingConfig.proxy.getAllowAllInbounds() + ? ipInterface + : ipLocal) + + "\n" + + tcontext.SettingsScreen.portSettingRule + ":" + tcontext.SettingsScreen.allowOtherHostsConnectTips( - hp: settingConfig.proxy.mixedPort, - sp: settingConfig.proxy.mixedPort) + + hp: settingConfig.proxy.mixedRulePort, + sp: settingConfig.proxy.mixedRulePort) + "\n" + tcontext.SettingsScreen.portSettingDirectAll + ":" + @@ -1977,25 +2121,8 @@ class _SettingScreenState extends LasyRenderingState { switchValue: settingConfig.proxy.enableCluster, onSwitch: (bool value) async { settingConfig.proxy.enableCluster = value; - SettingManager.setDirty(true); - if (value) { - bool? del = await DialogUtils.showConfirmDialog( - context, tcontext.SettingsScreen.clusterConfirm); - if (del == true) { - String? err = await ProxyCluster.start(); - if (err != null) { - DialogUtils.showAlertDialog( - context, err.toString()); - } - } else { - settingConfig.proxy.enableCluster = false; - setState(() {}); - } - } else { - await ProxyCluster.stop(); - } setState(() {}); })) : GroupItemOptions(), @@ -2005,7 +2132,10 @@ class _SettingScreenState extends LasyRenderingState { name: tcontext.SettingsScreen.clusterAllowOtherHostsConnect, tips: tcontext.SettingsScreen .clusterAllowOtherHostsConnectTips( - hp: settingConfig.proxy.clusterPort), + ip: settingConfig.proxy.getClusterAllowAllInbounds() + ? ipInterface + : ipLocal, + port: settingConfig.proxy.clusterPort), switchValue: settingConfig.proxy.getClusterAllowAllInbounds(), onSwitch: (bool value) async { @@ -2205,7 +2335,7 @@ class _SettingScreenState extends LasyRenderingState { GroupItemOptions( switchOptions: GroupItemSwitchOptions( name: tcontext.SettingsScreen.handleKaringScheme, - switchValue: await SystemSchemeUtils.isRegistered( + switchValue: SystemSchemeUtils.isRegistered( SystemSchemeUtils.getKaringScheme()), onSwitch: (bool value) async { String? error; @@ -2213,11 +2343,12 @@ class _SettingScreenState extends LasyRenderingState { error = await SystemSchemeUtils.register( SystemSchemeUtils.getKaringScheme()); } else { - error = await SystemSchemeUtils.unregister( + error = SystemSchemeUtils.unregister( SystemSchemeUtils.getKaringScheme()); } if (error != null) { - DialogUtils.showAlertDialog(context, error); + DialogUtils.showAlertDialog(context, error, + showCopy: true, showFAQ: true, withVersion: true); } setState(() {}); }, @@ -2225,7 +2356,7 @@ class _SettingScreenState extends LasyRenderingState { GroupItemOptions( switchOptions: GroupItemSwitchOptions( name: tcontext.SettingsScreen.handleClashScheme, - switchValue: await SystemSchemeUtils.isRegistered( + switchValue: SystemSchemeUtils.isRegistered( SystemSchemeUtils.getClashScheme()), onSwitch: (bool value) async { String? error; @@ -2233,11 +2364,12 @@ class _SettingScreenState extends LasyRenderingState { error = await SystemSchemeUtils.register( SystemSchemeUtils.getClashScheme()); } else { - error = await SystemSchemeUtils.unregister( + error = SystemSchemeUtils.unregister( SystemSchemeUtils.getClashScheme()); } if (error != null) { - DialogUtils.showAlertDialog(context, error); + DialogUtils.showAlertDialog(context, error, + showCopy: true, showFAQ: true, withVersion: true); } setState(() {}); }, @@ -2245,7 +2377,7 @@ class _SettingScreenState extends LasyRenderingState { GroupItemOptions( switchOptions: GroupItemSwitchOptions( name: tcontext.SettingsScreen.handleSingboxScheme, - switchValue: await SystemSchemeUtils.isRegistered( + switchValue: SystemSchemeUtils.isRegistered( SystemSchemeUtils.getSingboxScheme()), onSwitch: (bool value) async { String? error; @@ -2253,11 +2385,12 @@ class _SettingScreenState extends LasyRenderingState { error = await SystemSchemeUtils.register( SystemSchemeUtils.getSingboxScheme()); } else { - error = await SystemSchemeUtils.unregister( + error = SystemSchemeUtils.unregister( SystemSchemeUtils.getSingboxScheme()); } if (error != null) { - DialogUtils.showAlertDialog(context, error); + DialogUtils.showAlertDialog(context, error, + showCopy: true, showFAQ: true, withVersion: true); } setState(() {}); }, @@ -2370,7 +2503,8 @@ class _SettingScreenState extends LasyRenderingState { if (!exist && created) { await dir!.delete(); } - DialogUtils.showAlertDialog(context, err.toString()); + DialogUtils.showAlertDialog(context, err.toString(), + showCopy: true, showFAQ: true, withVersion: true); return; } await VPNService.uninit(); diff --git a/lib/screens/speedtest_settings_screen.dart b/lib/screens/speedtest_settings_screen.dart index 0f6a2ce..935e896 100644 --- a/lib/screens/speedtest_settings_screen.dart +++ b/lib/screens/speedtest_settings_screen.dart @@ -49,6 +49,7 @@ class _SpeedTestSettingsScreenState @override Widget build(BuildContext context) { final tcontext = Translations.of(context); + Size windowSize = MediaQuery.of(context).size; return Scaffold( appBar: PreferredSize( preferredSize: Size.zero, @@ -75,11 +76,16 @@ class _SpeedTestSettingsScreenState ), ), ), - Text( - tcontext.SpeedTestSettingsScreen.title, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2, + child: Text( + tcontext.SpeedTestSettingsScreen.title, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), InkWell( onTap: () async { @@ -199,8 +205,7 @@ class _SpeedTestSettingsScreenState text = text.trim(); Uri? uri = Uri.tryParse(text); if (uri == null || uri.scheme != "https") { - DialogUtils.showAlertDialog( - context, tcontext.SpeedTestSettingsScreen.error); + DialogUtils.showAlertDialog(context, tcontext.mustBeValidHttpsURL); return false; } diff --git a/lib/screens/text_to_qrcode_screen.dart b/lib/screens/text_to_qrcode_screen.dart index 87e4a5e..d2c8064 100644 --- a/lib/screens/text_to_qrcode_screen.dart +++ b/lib/screens/text_to_qrcode_screen.dart @@ -44,6 +44,7 @@ class _SentryTextToQrCodeScreenState @override Widget build(BuildContext context) { final tcontext = Translations.of(context); + Size windowSize = MediaQuery.of(context).size; return Scaffold( appBar: PreferredSize( preferredSize: Size.zero, @@ -68,11 +69,16 @@ class _SentryTextToQrCodeScreenState ), ), ), - Text( - tcontext.TextToQrCodeScreen.title, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2, + child: Text( + tcontext.TextToQrCodeScreen.title, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), const SizedBox( width: 50, @@ -119,7 +125,10 @@ class _SentryTextToQrCodeScreenState var result = QrcodeUtils.toImage(text); if (result.error != null) { DialogUtils.showAlertDialog( - context, result.error!.message); + context, result.error!.message, + showCopy: true, + showFAQ: true, + withVersion: true); } else { _image = result.data; } diff --git a/lib/screens/urltest_group_custom_screen.dart b/lib/screens/urltest_group_custom_screen.dart index 800a1b8..45f263e 100644 --- a/lib/screens/urltest_group_custom_screen.dart +++ b/lib/screens/urltest_group_custom_screen.dart @@ -48,6 +48,7 @@ class _UrlTestGroupCustomScreenState @override Widget build(BuildContext context) { final tcontext = Translations.of(context); + Size windowSize = MediaQuery.of(context).size; return Scaffold( appBar: PreferredSize( preferredSize: Size.zero, @@ -74,11 +75,16 @@ class _UrlTestGroupCustomScreenState ), ), ), - Text( - tcontext.urlTestCustomGroup, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2, + child: Text( + tcontext.urlTestCustomGroup, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), InkWell( onTap: () { diff --git a/lib/screens/urltest_settings_screen.dart b/lib/screens/urltest_settings_screen.dart index 97637d5..e3730f5 100644 --- a/lib/screens/urltest_settings_screen.dart +++ b/lib/screens/urltest_settings_screen.dart @@ -48,6 +48,7 @@ class _UrlTestSettingsScreenState @override Widget build(BuildContext context) { final tcontext = Translations.of(context); + Size windowSize = MediaQuery.of(context).size; return Scaffold( appBar: PreferredSize( preferredSize: Size.zero, @@ -74,11 +75,16 @@ class _UrlTestSettingsScreenState ), ), ), - Text( - tcontext.UrlTestSettingsScreen.title, - style: const TextStyle( - fontWeight: ThemeConfig.kFontWeightTitle, - fontSize: ThemeConfig.kFontSizeTitle), + SizedBox( + width: windowSize.width - 50 * 2, + child: Text( + tcontext.url, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), ), InkWell( onTap: () async { @@ -197,8 +203,7 @@ class _UrlTestSettingsScreenState text = text.trim(); Uri? uri = Uri.tryParse(text); if (uri == null || uri.scheme != "https") { - DialogUtils.showAlertDialog( - context, tcontext.UrlTestSettingsScreen.error); + DialogUtils.showAlertDialog(context, tcontext.mustBeValidHttpsURL); return false; } diff --git a/lib/screens/uwp_loopback_exemption_windows_screen.dart b/lib/screens/uwp_loopback_exemption_windows_screen.dart new file mode 100644 index 0000000..debcd49 --- /dev/null +++ b/lib/screens/uwp_loopback_exemption_windows_screen.dart @@ -0,0 +1,299 @@ +// ignore_for_file: unused_catch_stack + +import 'package:flutter/material.dart'; +import 'package:karing/app/utils/uwp_utils.dart'; +import 'package:karing/i18n/strings.g.dart'; +import 'package:karing/screens/dialog_utils.dart'; +import 'package:karing/screens/theme_config.dart'; +import 'package:karing/screens/theme_define.dart'; +import 'package:karing/screens/widgets/framework.dart'; + +class UWPLoopbackExemptionWindowsScreen extends LasyRenderingStatefulWidget { + static RouteSettings routSettings() { + return const RouteSettings(name: "UWPLoopbackExemptionWindowsScreen"); + } + + const UWPLoopbackExemptionWindowsScreen({super.key}); + + @override + State createState() => + _UWPLoopbackExemptionWindowsScreenState(); +} + +class _UWPLoopbackExemptionWindowsScreenState + extends LasyRenderingState { + bool? _checkAll; + bool _loading = true; + final List _searchedData = []; + final Set _netIsolation = {}; + final Set _checked = {}; + + @override + void initState() { + getUWPMappings(); + getUWPNetIsolation(); + super.initState(); + } + + @override + void dispose() { + super.dispose(); + } + + Future getUWPMappings() async { + if (!mounted) { + return; + } + _searchedData.clear(); + _loading = true; + List data = await UWPUtils.getMappings(); + if (!mounted) { + return; + } + _searchedData.addAll(data); + _searchedData.sort(sort); + _loading = false; + setState(() {}); + } + + Future getUWPNetIsolation() async { + if (!mounted) { + return; + } + _checked.clear(); + _netIsolation.clear(); + Set data = await UWPUtils.getNetIsolation(); + if (!mounted) { + return; + } + _netIsolation.addAll(data); + _checked.addAll(data); + setState(() {}); + } + + int sort(UWPMappings a, UWPMappings b) { + return a.name.compareTo(b.name); + } + + @override + Widget build(BuildContext context) { + final tcontext = Translations.of(context); + Size windowSize = MediaQuery.of(context).size; + return Scaffold( + appBar: PreferredSize( + preferredSize: Size.zero, + child: AppBar(), + ), + body: SafeArea( + child: Padding( + padding: const EdgeInsets.fromLTRB(0, 20, 0, 0), + child: Column( + children: [ + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + InkWell( + onTap: () => Navigator.pop(context), + child: const SizedBox( + width: 50, + height: 30, + child: Icon( + Icons.arrow_back_ios_outlined, + size: 26, + ), + ), + ), + SizedBox( + width: windowSize.width - 50 - 50 - 50, + child: Text( + tcontext.uwpExemption, + textAlign: TextAlign.center, + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: ThemeConfig.kFontWeightTitle, + fontSize: ThemeConfig.kFontSizeTitle), + ), + ), + Row( + children: [ + SizedBox( + width: 50, + height: 30, + child: Checkbox( + tristate: true, + value: _checkAll ?? false, + onChanged: (bool? value) { + _checkAll = value ?? false; + _checked.clear(); + if (_checkAll == true) { + for (var item in _searchedData) { + _checked.add(item.sid); + } + } + + setState(() {}); + }, + ), + ), + InkWell( + onTap: () async { + onTapDone(); + }, + child: const SizedBox( + width: 50, + height: 30, + child: Icon( + Icons.done, + size: 26, + ), + ), + ), + ], + ), + ], + ), + ), + const SizedBox( + height: 10, + ), + Expanded( + child: _loadListView(), + ), + ], + ), + ), + ), + ); + } + + Widget _loadListView() { + if (_loading) { + return const Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox( + width: 26, + height: 26, + child: RepaintBoundary( + child: CircularProgressIndicator(strokeWidth: 2), + ), + ) + ]); + } + Size windowSize = MediaQuery.of(context).size; + return Scrollbar( + thumbVisibility: true, + child: ListView.builder( + itemCount: _searchedData.length, + itemExtent: 66, + itemBuilder: (BuildContext context, int index) { + UWPMappings current = _searchedData[index]; + return createWidget(current, windowSize, index); + }, + )); + } + + Widget createWidget(UWPMappings current, Size windowSize, int index) { + return Container( + margin: const EdgeInsets.only(bottom: 2), + child: Material( + borderRadius: ThemeDefine.kBorderRadius, + child: InkWell( + onTap: () {}, + child: Container( + padding: const EdgeInsets.symmetric( + horizontal: 10, + ), + width: double.infinity, + //height: 66, + child: Row( + children: [ + Row( + children: [ + Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row(children: [ + const SizedBox( + width: 5, + ), + SizedBox( + width: 30, + child: Text( + (index + 1).toString(), + style: TextStyle( + fontSize: ThemeConfig.kFontSizeGroupItem), + ), + ), + const SizedBox( + width: 5, + ), + SizedBox( + width: windowSize.width - 110, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + current.name, + style: TextStyle( + fontSize: + ThemeConfig.kFontSizeGroupItem), + ), + current.sid == current.sid + ? const SizedBox.shrink() + : Text( + current.sid, + style: const TextStyle(fontSize: 12), + ), + ]), + ), + Checkbox( + tristate: true, + value: _checked.contains(current.sid), + onChanged: (bool? value) { + if (value == true) { + _checked.add(current.sid); + } else { + _checked.remove(current.sid); + } + setState(() {}); + }, + ), + ]), + ], + ), + ], + ), + ], + ), + ), + ), + ), + ); + } + + Future onTapDone() async { + if (_checked.isEmpty) { + await UWPUtils.SetNetIsolation(_netIsolation, false); + //await UWPUtils.ClearNetIsolation(); + } else if (_checked.isNotEmpty) { + Set inset = _checked.intersection(_netIsolation); + Set remove = _netIsolation.difference(inset); + Set add = _checked.difference(inset); + await UWPUtils.SetNetIsolation(remove, false); + await UWPUtils.SetNetIsolation(add, true); + } + + await getUWPNetIsolation(); + if (!mounted) { + return; + } + final tcontext = Translations.of(context); + DialogUtils.showAlertDialog(context, tcontext.done); + } +} diff --git a/lib/screens/version_update_screen.dart b/lib/screens/version_update_screen.dart index de44bf0..9fc5a01 100644 --- a/lib/screens/version_update_screen.dart +++ b/lib/screens/version_update_screen.dart @@ -140,7 +140,8 @@ class _VersionUpdateScreenState } if (res['isSuccess'] != true && res['errorMessage'] != "Install Cancel") { - DialogUtils.showAlertDialog(context, res['errorMessage']); + DialogUtils.showAlertDialog(context, res['errorMessage'], + showCopy: true, showFAQ: true, withVersion: true); } } } catch (err, stacktrace) { @@ -148,7 +149,8 @@ class _VersionUpdateScreenState if (!mounted) { return; } - DialogUtils.showAlertDialog(context, err.toString()); + DialogUtils.showAlertDialog(context, err.toString(), + showCopy: true, showFAQ: true, withVersion: true); } } } diff --git a/pubspec.lock b/pubspec.lock index 9935d8d..d66897f 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -165,10 +165,10 @@ packages: dependency: "direct main" description: name: crypto - sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27 + sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" url: "https://pub.flutter-io.cn" source: hosted - version: "3.0.5" + version: "3.0.6" cryptography: dependency: "direct main" description: @@ -253,10 +253,10 @@ packages: dependency: "direct dev" description: name: ffigen - sha256: "3e12e80ccb6539bb3917217bb6f32709220efb737de0d0fa8736da0b7cb507da" + sha256: a0ca4853028c6a9e4d9a0a40bb744fceb898c89d75931d08e87b3987d0087060 url: "https://pub.flutter-io.cn" source: hosted - version: "12.0.0" + version: "15.0.0" file: dependency: transitive description: @@ -306,26 +306,26 @@ packages: dependency: "direct dev" description: name: flutter_launcher_icons - sha256: "526faf84284b86a4cb36d20a5e45147747b7563d921373d4ee0559c54fcdbcea" + sha256: "619817c4b65b322b5104b6bb6dfe6cda62d9729bd7ad4303ecc8b4e690a67a77" url: "https://pub.flutter-io.cn" source: hosted - version: "0.13.1" + version: "0.14.1" flutter_lints: dependency: "direct dev" description: name: flutter_lints - sha256: "3f41d009ba7172d5ff9be5f6e6e6abb4300e263aab8866d2a0842ed2a70f8f0c" + sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1" url: "https://pub.flutter-io.cn" source: hosted - version: "4.0.0" + version: "5.0.0" flutter_local_notifications: dependency: "direct main" description: name: flutter_local_notifications - sha256: "49eeef364fddb71515bc78d5a8c51435a68bccd6e4d68e25a942c5e47761ae71" + sha256: "674173fd3c9eda9d4c8528da2ce0ea69f161577495a9cc835a2a4ecd7eadeb35" url: "https://pub.flutter-io.cn" source: hosted - version: "17.2.3" + version: "17.2.4" flutter_local_notifications_linux: dependency: transitive description: @@ -450,10 +450,10 @@ packages: dependency: "direct main" description: name: google_mobile_ads - sha256: d2ef5ec1e1f31137fc241bdeab3037c31062d387dd221fd884fb1160444c788b + sha256: "4775006383a27a5d86d46f8fb452bfcb17794fc0a46c732979e49a8eb1c8963f" url: "https://pub.flutter-io.cn" source: hosted - version: "4.0.0" + version: "5.2.0" hotkey_manager: dependency: "direct main" description: @@ -530,10 +530,10 @@ packages: dependency: "direct main" description: name: image - sha256: "2237616a36c0d69aef7549ab439b833fb7f9fb9fc861af2cc9ac3eedddd69ca8" + sha256: f31d52537dc417fdcde36088fdf11d191026fd5e4fae742491ebd40e5a8bea7d url: "https://pub.flutter-io.cn" source: hosted - version: "4.2.0" + version: "4.3.0" images_picker: dependency: "direct main" description: @@ -650,10 +650,10 @@ packages: dependency: transitive description: name: lints - sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235" + sha256: "3315600f3fb3b135be672bf4a178c55f274bebe368325ae18462c89ac1e3b413" url: "https://pub.flutter-io.cn" source: hosted - version: "4.0.0" + version: "5.0.0" logger: dependency: "direct main" description: @@ -730,42 +730,42 @@ packages: dependency: "direct main" description: name: open_dir - sha256: "84cff5b84a6b3ad7bfdfc3e8f03e85d86a6c8aea1d3472cf71546e2a6378ebbf" + sha256: a4884b00e5e5795a9b4b3d582ac6a66e9196795ed760dbc3c63b4837c70c5901 url: "https://pub.flutter-io.cn" source: hosted - version: "0.0.1+6" + version: "0.0.2+1" open_dir_linux: dependency: transitive description: name: open_dir_linux - sha256: "018287c9d3ecc4dcbb2f299fc704e33908ea9d570b8cf1d2af6a9b57a1af6426" + sha256: "3c68f13933bdd0b9e1bcb5bf1f3451e8f284fc2972e88b99371b51bf09963eed" url: "https://pub.flutter-io.cn" source: hosted - version: "0.0.1+2" + version: "0.0.2" open_dir_macos: dependency: transitive description: name: open_dir_macos - sha256: f35d85cc20872bf6eb79623d6559b82f98115fed2ec4fe4fbb4539dd0d3f007c + sha256: "51fdc8c3a06c9d571b599b5901045ada23d1440b24c3052c0a66cf3ee4ac901b" url: "https://pub.flutter-io.cn" source: hosted - version: "0.0.1+2" + version: "0.0.2" open_dir_platform_interface: dependency: transitive description: name: open_dir_platform_interface - sha256: "405a6f89849af379c3de7ad5a2551fab219da36089d14623b1469550dcd7d8c9" + sha256: ca189abb02d8e3320f9b2493b6d58e3a33f393d5eb4ccbbef02e0bc0fd393872 url: "https://pub.flutter-io.cn" source: hosted - version: "0.0.1+2" + version: "0.0.2" open_dir_windows: dependency: transitive description: name: open_dir_windows - sha256: ca6baff2aef2479f6afea83ae0b66c976cdc05709c1cd969607ae2babbc9ab24 + sha256: b36b9399c3d4020460e699a40be98e6e081683d2b0dc8e14e685017e06ad4f37 url: "https://pub.flutter-io.cn" source: hosted - version: "0.0.1+3" + version: "0.0.2" open_file: dependency: "direct main" description: @@ -778,42 +778,42 @@ packages: dependency: transitive description: name: open_file_android - sha256: eaa52421c5e10ba42eb3958d2632be0fc8b4f7e53556296064339d363caa2233 + sha256: "58141fcaece2f453a9684509a7275f231ac0e3d6ceb9a5e6de310a7dff9084aa" url: "https://pub.flutter-io.cn" source: hosted - version: "1.0.3" + version: "1.0.6" open_file_ios: dependency: transitive description: name: open_file_ios - sha256: "8d9c03495cf14ca70bdbf191894b822ba3b2629cc0046ee311cbbe504db66c44" + sha256: "02996f01e5f6863832068e97f8f3a5ef9b613516db6897f373b43b79849e4d07" url: "https://pub.flutter-io.cn" source: hosted - version: "1.0.2" + version: "1.0.3" open_file_linux: dependency: transitive description: name: open_file_linux - sha256: cd2088722048b9c40f8615c6d83005fe0726e0e447e9cdfb40c2b65477291f7d + sha256: d189f799eecbb139c97f8bc7d303f9e720954fa4e0fa1b0b7294767e5f2d7550 url: "https://pub.flutter-io.cn" source: hosted - version: "0.0.4" + version: "0.0.5" open_file_mac: dependency: transitive description: name: open_file_mac - sha256: "9d809f528cccc6dc9390caf50893eae9a6944e0f3b8a2558c7ad19e91c9244a1" + sha256: dd1570bd12601b4d50fda3609c1662382f17ee403b47f0d74d737de603a39ec6 url: "https://pub.flutter-io.cn" source: hosted - version: "1.0.1" + version: "1.0.2" open_file_platform_interface: dependency: transitive description: name: open_file_platform_interface - sha256: "14c50efb1a9667cb96e4fa68d601e6ad348fe337b02789834029b37ae3631498" + sha256: "101b424ca359632699a7e1213e83d025722ab668b9fd1412338221bf9b0e5757" url: "https://pub.flutter-io.cn" source: hosted - version: "1.0.2" + version: "1.0.3" open_file_web: dependency: transitive description: @@ -826,10 +826,10 @@ packages: dependency: transitive description: name: open_file_windows - sha256: "2f4318d2d3958ec8d63b6dd4430c15b1fcb2fe7a2113e83c734584501a5c6d81" + sha256: d26c31ddf935a94a1a3aa43a23f4fff8a5ff4eea395fe7a8cb819cf55431c875 url: "https://pub.flutter-io.cn" source: hosted - version: "0.0.2" + version: "0.0.3" package_config: dependency: transitive description: @@ -974,6 +974,22 @@ packages: url: "https://pub.flutter-io.cn" source: hosted version: "6.1.2" + pub_semver: + dependency: transitive + description: + name: pub_semver + sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" + url: "https://pub.flutter-io.cn" + source: hosted + version: "2.1.4" + punycode_converter: + dependency: "direct main" + description: + name: punycode_converter + sha256: "02d77b16c40ce9503ade3897eae6e72f2c1621a0f873be2d25bbf898c0663df8" + url: "https://pub.flutter-io.cn" + source: hosted + version: "0.2.1" qr_code_scanner: dependency: "direct main" description: @@ -1042,10 +1058,10 @@ packages: dependency: "direct main" description: name: scrollview_observer - sha256: a07a5694758801cd3ff45ef67f78f4abf2bc309cbbcf0e7b0c3edd44f2f54b1c + sha256: fa408bcfd41e19da841eb53fc471f8f952d5ef818b854d2505c4bb3f0c876381 url: "https://pub.flutter-io.cn" source: hosted - version: "1.21.2" + version: "1.22.0" sentry: dependency: transitive description: @@ -1111,18 +1127,18 @@ packages: dependency: "direct main" description: name: slang - sha256: a2f704508bf9f209b71c881347bd27de45309651e9bd63570e4dd6ed2a77fbd2 + sha256: b04db2dbaf927b28600a2f8a272a3bf2ae309556dcc5d6beb02d66af0be39e4c url: "https://pub.flutter-io.cn" source: hosted - version: "3.31.2" + version: "4.1.0" slang_flutter: dependency: "direct main" description: name: slang_flutter - sha256: f8400292be49c11697d94af58d7f7d054c91af759f41ffe71e4e5413871ffc62 + sha256: "59988f37bb8b50d96ee46832a8a389036c0da26c04b1b1d4aa6690c00f70eccf" url: "https://pub.flutter-io.cn" source: hosted - version: "3.31.0" + version: "4.1.0" source_span: dependency: transitive description: @@ -1239,10 +1255,10 @@ packages: dependency: "direct main" description: name: url_launcher - sha256: "21b704ce5fa560ea9f3b525b43601c678728ba46725bab9b01187b4831377ed3" + sha256: "9d06212b1362abc2f0f0d78e6f09f726608c74e3b9462e8368bb03314aa8d603" url: "https://pub.flutter-io.cn" source: hosted - version: "6.3.0" + version: "6.3.1" url_launcher_android: dependency: transitive description: @@ -1374,10 +1390,10 @@ packages: dependency: "direct main" description: name: web_socket_channel - sha256: "939ab60734a4f8fa95feacb55804fa278de28bdeef38e616dc08e44a84adea23" + sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b url: "https://pub.flutter-io.cn" source: hosted - version: "2.4.3" + version: "2.4.0" webdav_client: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 089047e..a41e500 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -17,11 +17,11 @@ publish_to: none # Remove this line if you wish to publish to pub.dev # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 1.0.30+414 +version: 1.0.32+435 environment: sdk: ">=3.2.3 <4.0.0" - flutter: ">=3.10.0" + flutter: ">=3.24.0" # Dependencies specify other packages that your package needs in order to work. # To automatically upgrade your package dependencies to the latest versions @@ -48,11 +48,11 @@ dependencies: #device_info_plus: ^9.1.1 #https://developer.apple.com/support/third-party-SDK-requirements/ #network_info_plus: ^4.0.1 #connectivity_plus: ^4.0.1 - package_info_plus: ^5.0.1 + package_info_plus: ^5.0.1 #sentry_flutter #platform_device_id: ^1.0.1 class_to_string: ^1.0.0 ffi: ^2.1.3 - url_launcher: ^6.3.0 + url_launcher: ^6.3.1 web_socket_channel: ^2.4.0 #flutter_test #sqlite3_flutter_libs: ^0.5.17 #sqlite_async: ^0.5.2 @@ -79,43 +79,44 @@ dependencies: #fpdart: ^1.1.0 zxing2: ^0.2.3 qr_code_scanner: ^1.0.1 - screen_capturer: ^0.2.2 #pc only + screen_capturer: ^0.2.3 #pc only contextmenu: ^3.0.0 - image: ^4.2.0 + image: ^4.3.0 uuid: ^4.4.0 #flutter_test - slang: ^3.31.1 - slang_flutter: ^3.31.0 + slang: ^4.1.0 + slang_flutter: ^4.1.0 watcher: ^1.1.0 string_validator: ^1.1.0 + punycode_converter: ^0.2.1 #pay: ^1.1.0 #alipay_kit: ^5.0.0 yaml: ^3.1.2 - country: ^4.1.8 - scrollview_observer: ^1.21.0 + country: ^4.1.9 + scrollview_observer: ^1.22.0 after_layout: ^1.2.0 #animated_toggle_switch: ^0.8.0 install_referrer: ^1.2.1 windows_single_instance: ^1.0.1 #windows only file_picker: ^6.1.1 images_picker: ^1.2.11 - tray_manager: ^0.2.3 # pc only + tray_manager: ^0.2.4 # pc only hotkey_manager: ^0.2.3 # pc only #accessibility_tools: ^2.2.2 android_package_manager: ^0.7.1 logger: ^2.4.0 tuple: ^2.0.2 - crypto: ^3.0.5 + crypto: ^3.0.6 cryptography: ^2.7.0 cryptography_flutter: ^2.3.2 - open_dir: ^0.0.1+6 # pc only + open_dir: ^0.0.2+1 #pc only in_app_review: ^2.0.9 path: ^1.8.3 #flutter_test - characters: ^1.3.0 - win32_registry: ^1.1.4 + characters: ^1.3.0 #flutter_test + win32_registry: ^1.1.5 csv: ^6.0.0 #home_widget: ^0.4.1 - share_plus: ^7.2.2 - open_file: ^3.4.0 + share_plus: ^7.2.2 #sentry_flutter + open_file: ^3.4.0 #sentry_flutter install_plugin: ^2.1.0 move_to_background: ^1.0.2 #dart_ping: ^9.0.1 @@ -132,9 +133,12 @@ dependencies: #code_text_field: ^1.1.0 #flutter_speed_dial: ^7.0.0 flutter_inapp_notifications: ^1.0.0 - flutter_local_notifications: ^17.2.2 + flutter_local_notifications: ^17.2.4 #awesome_notifications: ^0.9.2 #flutter_shortcuts: ^1.3.0 + google_mobile_ads: ^5.2.0 #>=5.0 need xcode 1.53, macos 14 + #easy_audience_network: ^0.0.7 + #easy_ads_flutter: ^2.7.0 window_manager: #^0.3.7 #pc only #path: ../window_manager/ git: @@ -155,7 +159,7 @@ dependencies: dev_dependencies: sentry_dart_plugin: 2.0.0 - flutter_launcher_icons: ^0.13.1 + flutter_launcher_icons: ^0.14.1 flutter_test: sdk: flutter @@ -164,8 +168,8 @@ dev_dependencies: # activated in the `analysis_options.yaml` file located at the root of your # package. See that file for information about deactivating specific lint # rules and activating additional ones. - flutter_lints: ^4.0.0 - ffigen: ^12.0.0 # install llvm, https://pub.dev/packages/ffigen,build:dart run ffigen + flutter_lints: ^5.0.0 + ffigen: ^15.0.0 # install llvm, https://pub.dev/packages/ffigen,build:dart run ffigen # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec diff --git a/web/favicon.png b/web/favicon.png index 8aaa46a..b32b1a1 100644 Binary files a/web/favicon.png and b/web/favicon.png differ diff --git a/web/icons/Icon-192.png b/web/icons/Icon-192.png deleted file mode 100644 index b749bfe..0000000 Binary files a/web/icons/Icon-192.png and /dev/null differ diff --git a/web/icons/Icon-512.png b/web/icons/Icon-512.png deleted file mode 100644 index 88cfd48..0000000 Binary files a/web/icons/Icon-512.png and /dev/null differ diff --git a/web/icons/Icon-maskable-192.png b/web/icons/Icon-maskable-192.png deleted file mode 100644 index eb9b4d7..0000000 Binary files a/web/icons/Icon-maskable-192.png and /dev/null differ diff --git a/web/icons/Icon-maskable-512.png b/web/icons/Icon-maskable-512.png deleted file mode 100644 index d69c566..0000000 Binary files a/web/icons/Icon-maskable-512.png and /dev/null differ