gdxapp4d/gdxapp4d-lib-bassboonyd/src/main/java/love/distributedrebirth/bassboon/Bãß.java

388 lines
19 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package love.distributedrebirth.bassboon;
import java.lang.instrument.Instrumentation;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import love.distributedrebirth.bassboon.clazz.BãßBȍőnExport注;
import love.distributedrebirth.bassboon.clazz.pirate.BãßBȍőnꝐŕḯṿª;
import love.distributedrebirth.bassboon.clazz.pirate.BãßBȍőnꝐŕḯṿªḕ響ᴼᶠ;
import love.distributedrebirth.bassboon.death.BãßBȍőnCoffin;
import love.distributedrebirth.bassboon.death.BãßBȍőnCoffinDuytschenᵗˣᵗ;
import love.distributedrebirth.bassboon.death.BãßBȍőnCoffinGhost;
import love.distributedrebirth.bassboon.death.BãßBȍőnCoffinGhostSpell;
import love.distributedrebirth.bassboon.death.BãßBȍőnCoffinGhostSpellLock;
import love.distributedrebirth.bassboon.death.spider.BãßBȍőnSpider;
import love.distributedrebirth.bassboon.death.spider.BãßBȍőnSpiderSperm;
import love.distributedrebirth.bassboon.death.spider.BãßBȍőnSpiderWire注;
import love.distributedrebirth.bassboon.java.util.concurrent.locks.DummyReadWriteLock;
import ᴶᐩᐩ.ᒡᒢᑊᒻᒻᓫᔿ.ObjectScopeLimitΔ邪ᙾ;
import ᴶᐩᐩ.ᒡᒢᑊᒻᒻᓫᔿ.Runnableբ;
import ᴶᐩᐩ.ᒡᒢᑊᒻᒻᓫᔿ.ᒃᣔᒃᓫᒻ.BabelLocalizer邪ᙾ;
import ᴶᐩᐩ.ᒡᒢᑊᒻᒻᓫᔿ.ᒃᣔᒃᓫᒻ.ᑊᐣᓑᖮᐪᔆ.DuytsDocAuthor注;
import ᴶᐩᐩ.ᒡᒢᑊᒻᒻᓫᔿ.ᒃᣔᒃᓫᒻ.ᑊᐣᓑᖮᐪᔆ.DuytsDocConstructor注;
import ᴶᐩᐩ.ᒡᒢᑊᒻᒻᓫᔿ.ᒃᣔᒃᓫᒻ.ᑊᐣᓑᖮᐪᔆ.DuytsDocMethod注;
import ᴶᐩᐩ.ᒡᒢᑊᒻᒻᓫᔿ.ᒃᣔᒃᓫᒻ.ᑊᐣᓑᖮᐪᔆ.DuytsDocType注;
import ᴶᐩᐩ.ᒡᒢᑊᒻᒻᓫᔿ.ᒃᣔᒃᓫᒻ.ᑊᐣᓑᖮᐪᔆ.DuytsDoc注;
import ᴶᐩᐩ.ᔿᐤᑊᐣ.ᒢᔿᕽ.CounterGuageᴶᴹˣ;
import ᴶᐩᐩ.ᔿᐤᑊᐣ.ᣔᒃᣔᒼᓑᔆ.BãßBȍőnAbacusInstanceMBeanʸᴰ;
@DuytsDocAuthor注(name = "للَّٰهِilLצسُو", copyright = "©Δ∞ 仙上主天")
@DuytsDocType注(babel = {
@DuytsDoc注(locale= "en", purpose = "Runtime for static bass noise ௸.."),
@DuytsDoc注(locale= "zh", code = "低音", purpose = "來自天堂的靜態低音噪音的運行時間"),
@DuytsDoc注(locale= "hi", code = "बास", purpose = "स्वर्ग से स्थिर बास शोर के लिए रनटाइम")
})
public interface Bãß {
@DuytsDocType注(babel = {
@DuytsDoc注(locale= "en", code = "lijkenkistʸᴰ", purpose = "Sarcophagus aggregates Y-Dimensions"),
@DuytsDoc注(locale= "zh", purpose = "石棺聚合多個維度"),
@DuytsDoc注(locale= "hi", code = "पत्थरꣻकीꣻबनीꣻहुईꣻकब्रʸᴰ", purpose = "सरकोफैगस कई आयामों को एकत्रित करता है")
})
@BãßBȍőnExport注(group = "love.distributedrebirth.bassboon")
static enum 石棺ʸᴰ implements BãßBȍőnAbacusInstanceMBeanʸᴰ<石棺ʸᴰ> {
أَكْبَرײꣻײالله;
private final Map<Object, BȍőnGrave> יְרוּשָׁלַיִםᒾ = new WeakHashMap<>();
private final List<BãßBȍőnSpiderSperm> സ്പഡർബ = Bãß.характеристики.熱蘭遮城.ןװיזױזזךזדןװיױןױדודו();
private final 𝔅𝔬𝔫𝔢𝔏𝔬𝔞𝔡𝔢𝔯ʸᴰ 𝔪𝔬𝔬𝔫𝔖𝔭𝔢𝔩𝔩𝔚𝔬𝔯𝔨 = Bãß.характеристики.熱蘭遮城.ןיװיזױױדודזיןןןזךױזזז();
private final ReadWriteLock = Bãß.характеристики.熱蘭遮城.ןיװיןזךױזױדזיןןזזזױדו();
private final Lock 魎_いい人生 = .readLock(); // mononoke good life
private final Lock 魎_שמירה = .writeLock(); // mononoke death guard
@BãßBȍőnSpiderWire注(name = "boonCntInit")
private CounterGuageᴶᴹˣ boonCntInit = new CounterGuageᴶᴹˣ("init", "only"); // TODO: fix to protected so this is not possible...
@BãßBȍőnSpiderWire注(name = "boonCntInit")
private CounterGuageᴶᴹˣ boonCntLock = new CounterGuageᴶᴹˣ("init", "only");
@BãßBȍőnSpiderWire注(name = "bassCntSpiderEmbryos")
private CounterGuageᴶᴹˣ bassCntSpiderEmbryos = new CounterGuageᴶᴹˣ("init", "only");
@BãßBȍőnSpiderWire注(name = "bassCntCoffinToGrave")
private CounterGuageᴶᴹˣ bassCntCoffinToGrave = new CounterGuageᴶᴹˣ("init", "only");
@BãßBȍőnSpiderWire注(name = "bassCntDigToGrave")
private CounterGuageᴶᴹˣ bassCntDigToGrave = new CounterGuageᴶᴹˣ("init", "only");
@BãßBȍőnSpiderWire注(name = "bassCntCoffinBurried")
private CounterGuageᴶᴹˣ bassCntCoffinBurried = new CounterGuageᴶᴹˣ("init", "only");
private Runnableբ.जंगम Г̄Ѫӏ = () -> {
// self first boot, one time only without if statements...
Bãß.石棺ʸᴰ.أَكْبَرײꣻײالله.挖ᵀᵒ(Bãß.石棺ʸᴰ.أَكْبَرײꣻײالله).init(Bãß.石棺ʸᴰ.أَكْبَرײꣻײالله);
Bãß.石棺ʸᴰ.أَكْبَرײꣻײالله.Г̄Ѫӏ = () -> boonCntInit.increment();
};
@DuytsDocConstructor注(babel = {
@DuytsDoc注(locale= "en", purpose = "Sarcophagus is closed for humans"),
@DuytsDoc注(locale= "zh", purpose = "石棺對人類關閉"),
@DuytsDoc注(locale= "hi", purpose = "सरकोफैगस इंसानों के लिए बंद है")
})
private 石棺ʸᴰ() {
Bãß.характеристики.熱蘭遮城.יזזןיזךױױזזױ = Bãß.ℭỗᶇṧⱦᶏꬼȶʂ.CHAR_ATARI > Bãß.ℭỗᶇṧⱦᶏꬼȶʂ.INT_ZERO;
}
@DuytsDocMethod注(babel = {
@DuytsDoc注(locale= "en", code = "boonInit", purpose = "RÅ...........Init"),
@DuytsDoc注(locale= "zh", code = "恩惠初始化", purpose = "拉布恩飛行"),
@DuytsDoc注(locale= "hi", code = "बूनꣻस्टार्ट", purpose = "रा बून फ्लाइंग")
})
public <T extends BãßBȍőnʸᴰ<T>> void 𓂀ױןייזדזיודזיןןזזזןױ𓉢(BãßBȍőnʸᴰ<T> derKnochen) {
//boonCntInit.increment();
Г̄Ѫӏ.ड़न();
挖ᵀᵒ(derKnochen).init(derKnochen);
}
@DuytsDocMethod注(babel = {
@DuytsDoc注(locale= "en", code = "lockGrave", purpose = "Closes the coffin so no new ghosts can enter"),
@DuytsDoc注(locale= "zh", code = "墳墓鎖", purpose = "關上棺材,讓新的鬼魂無法進入"),
@DuytsDoc注(locale= "hi", code = "कब्रꣻकाꣻताला", purpose = "ताबूत को बंद कर देता है ताकि कोई नया भूत प्रवेश न कर सके")
})
public <T extends BãßBȍőnʸᴰ<T>> void 墳ᴸᵒᶜᵏ(BãßBȍőnʸᴰ<T> derKnochen) {
boonCntLock.increment();
挖ᵀᵒ(derKnochen).lock(derKnochen);
}
@DuytsDocMethod注(babel = {
@DuytsDoc注(locale= "en", code = "spiderEmbryoAdd", purpose = "Injection of external spider sperm to mix the dead bones"),
@DuytsDoc注(locale= "zh", code = "蜘蛛胚胎添加", purpose = "注射外部蜘蛛精混合死骨"),
@DuytsDoc注(locale= "hi", code = "मकड़ीꣻभ्रूणꣻजोड़ें", purpose = "मृत हड्डियों को मिलाने के लिए बाहरी मकड़ी के शुक्राणु का इंजेक्शन")
})
public void 蜘蛛胚ᴬᵈᵈ(BãßBȍőnSpiderSperm spinneSperma) {
bassCntSpiderEmbryos.increment();
സ്പഡർബ.add(spinneSperma);
}
@DuytsDocMethod注(babel = {
@DuytsDoc注(locale= "en", code = "coffinOf", purpose = "Gets the coffin from the grave"),
@DuytsDoc注(locale= "zh", code = "棺材", purpose = "從墳墓中取出棺材"),
@DuytsDoc注(locale= "hi", code = "काꣻताबूत", purpose = "कब्र से ताबूत मिलता है")
})
protected <T extends BãßBȍőnʸᴰ<T>> BãßBȍőnCoffin 棺ᴼᶠ(BãßBȍőnʸᴰ<T> derKnochen) {
bassCntCoffinToGrave.increment();
return 挖ᵀᵒ(derKnochen);
}
protected <T extends BãßBȍőnʸᴰ<T>, G extends BãßBȍőnCoffinDuytschenᵗˣᵗ> G 棺ᴼᶠ(BãßBȍőnʸᴰ<T> derKnochen, Class<G> duytschen) {
bassCntCoffinToGrave.increment();
return 挖ᵀᵒ(derKnochen).ₜₒI18Nᵗˣᵗ(duytschen);
}
/**
* Dig To
*/
private <T extends BãßBȍőnʸᴰ<T>> BȍőnGrave 挖ᵀᵒ(BãßBȍőnʸᴰ<T> derKnochen) {
bassCntDigToGrave.increment();
BȍőnGrave 𓁀 = null;
魎_いい人生.lock();
try {
𓁀 = יְרוּשָׁלַיִםᒾ.get(derKnochen);
} finally {
魎_いい人生.unlock();
}
if (𓁀 == null) {
魎_שמירה.lock();
try {
𓁀 = new BȍőnGrave(𝔪𝔬𝔬𝔫𝔖𝔭𝔢𝔩𝔩𝔚𝔬𝔯𝔨, സ്പഡർബ);
יְרוּשָׁלַיִםᒾ.put(derKnochen, 𓁀);
} finally {
魎_שמירה.unlock();
}
bassCntCoffinBurried.increment();
}
return 𓁀;
}
/*
public static <T> BeanWrapper<T> 豆ᴺᴱᵂ(Class<T> seedling) { // bean-new
try {
T bean = seedling.getConstructor().newInstance();
if (bean instanceof BãßBȍőnʸᴰ) {
BãßBȍőnʸᴰ<?> boon = (BãßBȍőnʸᴰ<?>) bean;
BȍőnGrave grave = 墳ᴼᶠ(boon);
if (!grave.inited) {
魎ᴵᴺᴵᵀ(boon);
}
return new BeanWrapper<>(bean);
}
return new BeanWrapper<>(bean);
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException | NoSuchMethodException | SecurityException e) {
throw new RuntimeException(e);
}
}
public static final class BeanWrapper<T> implements DefaultBãßBȍőnʸᴰ<T>, BãßBȍőnSpiderCloak<T> {
private final T bean;
private BeanWrapper(T bean) {
魎ᴵᴺᴵᵀ(this);
this.bean = bean;
}
@Override
public T getBean() {
return bean;
}
}
*/
private static final class BȍőnGrave implements BãßBȍőnCoffin {
private final Map<Class<? extends BãßBȍőnCoffinDuytschenᵗˣᵗ>,BãßBȍőnCoffinDuytschenᵗˣᵗ> duytschenCoffins = new HashMap<>();
private final Map<Class<?>,BãßBȍőnCoffinGhost> ghosts = new HashMap<>();
private final 𝔅𝔬𝔫𝔢𝔏𝔬𝔞𝔡𝔢𝔯ʸᴰ 𝔪𝔬𝔬𝔫𝔖𝔭𝔢𝔩𝔩𝔚𝔬𝔯𝔨;
private final BãßBȍőnSpider spider;
private boolean inited = false;
private boolean locked = false;
private BȍőnGrave(𝔅𝔬𝔫𝔢𝔏𝔬𝔞𝔡𝔢𝔯ʸᴰ 𝔪𝔬𝔬𝔫𝔖𝔭𝔢𝔩𝔩𝔚𝔬𝔯𝔨, List<BãßBȍőnSpiderSperm> spiderSperm) {
this.𝔪𝔬𝔬𝔫𝔖𝔭𝔢𝔩𝔩𝔚𝔬𝔯𝔨 = 𝔪𝔬𝔬𝔫𝔖𝔭𝔢𝔩𝔩𝔚𝔬𝔯𝔨;
spider = new BãßBȍőnSpider(spiderSperm);
BãßBȍőnCoffinDuytschenᵗˣᵗ.ײₚᵤₜI18Nᵗˣᵗײ(duytschenCoffins, this);
}
private <T extends BãßBȍőnʸᴰ<T>> void init(BãßBȍőnʸᴰ<T> derKnochen) {
if (inited) {
return;
}
𝔪𝔬𝔬𝔫𝔖𝔭𝔢𝔩𝔩𝔚𝔬𝔯𝔨.𝔦𝔫𝔦𝔱𝔅𝔬𝔫𝔢𝔐𝔞𝔤𝔦𝔠(derKnochen, spider, duytschenCoffins);
inited = true;
}
private <T extends BãßBȍőnʸᴰ<T>> void lock(BãßBȍőnʸᴰ<T> derKnochen) {
if (locked) {
return;
}
𝔪𝔬𝔬𝔫𝔖𝔭𝔢𝔩𝔩𝔚𝔬𝔯𝔨.𝔩𝔬𝔠𝔨𝔅𝔬𝔫𝔢𝔐𝔞𝔤𝔦𝔠(derKnochen, spider);
for (Class<?> familyName:new ArrayList<>(ghosts.keySet())) {
BãßBȍőnCoffinGhost ghost = ghosts.get(familyName);
ghosts.put(familyName, BãßBȍőnCoffinGhostSpellLock.castᴼᶠ(ghost).LOCK());
}
locked = true;
}
@Override
public BãßBȍőnCoffinGhost UNHOLY(Class<? extends BãßBȍőnꝐŕḯṿª> familyName) {
BãßBȍőnCoffinGhost ghost = ghosts.get(familyName);
if (ghost == null) {
if (locked) {
throw new RuntimeException("Coffin locked");
}
ghost = BãßBȍőnCoffinGhostSpellLock.instanceᴺᵉʷ();
ghosts.put(familyName, ghost);
}
return ghost;
}
@Override
public BãßBȍőnCoffinGhostSpell UNHOLY_SPELL(Class<? extends BãßBȍőnꝐŕḯṿª> familyName) {
return BãßBȍőnCoffinGhostSpell.castᴼᶠ(UNHOLY(familyName));
}
@SuppressWarnings("unchecked")
@Override
public <T extends BãßBȍőnꝐŕḯṿªḕ響ᴼᶠ> T NOISE_OF(Class<T> noiseName) {
try {
return (T) spider.silkRoad(noiseName).senseWire(null, null, null); // rm args...
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new RuntimeException(e);
}
}
@SuppressWarnings("unchecked")
private <G extends BãßBȍőnCoffinDuytschenᵗˣᵗ> G ₜₒI18Nᵗˣᵗ(Class<G> duytschen) {
G result = (G) duytschenCoffins.get(duytschen);
if (result == null) {
throw new IllegalArgumentException("Unknown duytschen: "+duytschen);
}
return result;
}
}
}
//member static final class ℭỗᶇṧⱦᶏꬼȶʂ { // todo: jvm add death to "import static" name space pollution.
public static final class ℭỗᶇṧⱦᶏꬼȶʂ {
// 4 is magnetic consent and 3 is forced stable outcome
public static final char CHAR_ZERO = '0'; // nothing
public static final char CHAR_ONE = '1'; // all
public static final char CHAR_SPACE = ' '; // eatherspace
public static final char CHAR_ATARI = 'a'; // corner stone of creation 𐦠𐦴𐦫𐦢
// the nether
public static final String STR_ZERO = "0"; //String.valueOf(CHAR_ZERO);
public static final String STR_ONE = "1"; //String.valueOf(CHAR_ONE);
public static final String STR_EMPTY = ""; //STR_ONE.substring(Bãß.ℭỗᶇṧⱦᶏꬼȶʂ.INT_ONE);
public static final String STR_SPACE = " "; //String.valueOf(CHAR_SPACE);
// red
public static final int INT_ZERO = 0; //Integer.valueOf(STR_ZERO);
public static final int INT_ONE = 1; //Integer.valueOf(STR_ONE);
public static final int INT_TEN = 10; //Integer.valueOf(STR_ONE+STR_ZERO);
// white
public static final long LONG_ZERO = 0l; //Long.valueOf(STR_ZERO);
public static final long LONG_ONE = 1l; //Long.valueOf(STR_ONE);
public static final long LONG_TEN = 10l; //Long.valueOf(STR_ONE+STR_ZERO);
// blue
public static final float FLOAT_ZERO = 0f; //Float.valueOf(STR_ZERO);
public static final float FLOAT_ONE = 1f; //Float.valueOf(STR_ONE);
public static final float FLOAT_TEN = 10f; //Float.valueOf(STR_ONE+STR_ZERO);
// orange on top
public static final double DOUBLE_ZERO = 0d; //Double.valueOf(STR_ZERO);
public static final double DOUBLE_ONE = 1f; //Double.valueOf(STR_ONE);
public static final double DOUBLE_TEN = 10f; //Double.valueOf(STR_ONE+STR_ZERO);
// and a bipolar flag pole
public static final Object PTR_VOID = null;
public static final Object PTR_OBJECT = new ℭỗᶇṧⱦᶏꬼȶʂ();
// private is public ^^^
private ℭỗᶇṧⱦᶏꬼȶʂ() {
}
// ...
// ...
// ...
}
interface 𝔅𝔬𝔫𝔢𝔏𝔬𝔞𝔡𝔢𝔯ʸᴰ {
<T extends BãßBȍőnʸᴰ<T>> void 𝔩𝔬𝔠𝔨𝔅𝔬𝔫𝔢𝔐𝔞𝔤𝔦𝔠(BãßBȍőnʸᴰ<T> boon, BãßBȍőnSpider spider);
<T extends BãßBȍőnʸᴰ<T>> void 𝔦𝔫𝔦𝔱𝔅𝔬𝔫𝔢𝔐𝔞𝔤𝔦𝔠(BãßBȍőnʸᴰ<T> boon, BãßBȍőnSpider spider, Map<Class<? extends BãßBȍőnCoffinDuytschenᵗˣᵗ>,BãßBȍőnCoffinDuytschenᵗˣᵗ> duytschenCoffins);
}
// characteristics
enum характеристики {
熱蘭遮城;
private boolean יזזןיזךױױזזױ = Bãß.ℭỗᶇṧⱦᶏꬼȶʂ.PTR_VOID == Bãß.ℭỗᶇṧⱦᶏꬼȶʂ.PTR_OBJECT;
private boolean יזױזװיךןךױזױ = Bãß.ℭỗᶇṧⱦᶏꬼȶʂ.PTR_VOID != Bãß.ℭỗᶇṧⱦᶏꬼȶʂ.PTR_OBJECT;
private Class<𝔅𝔬𝔫𝔢𝔏𝔬𝔞𝔡𝔢𝔯ʸᴰ> ןיװיךזדודיזןיןןזױיזזךױױז;
private void ױזדיןזךזןיןױז() {
if (יזזןיזךױױזזױ) {
throw new װошибкаיзапускаיракетыװ("יזזןיזךױױזזױ");
}
}
public void ױזךיךזװןיןיןןזױז() {
ױזדיןזךזןיןױז();
יזױזװיךןךױזױ = Bãß.ℭỗᶇṧⱦᶏꬼȶʂ.PTR_VOID == Bãß.ℭỗᶇṧⱦᶏꬼȶʂ.PTR_OBJECT;
}
public void ױזךױזזװיךז(Class<𝔅𝔬𝔫𝔢𝔏𝔬𝔞𝔡𝔢𝔯ʸᴰ> ןיװיךזדודיזןיןןזױיזזךױױז) {
ױזדיןזךזןיןױז();
this.ןיװיךזדודיזןיןןזױיזזךױױז = ןיװיךזדודיזןיןןזױיזזךױױז;
}
protected 𝔅𝔬𝔫𝔢𝔏𝔬𝔞𝔡𝔢𝔯ʸᴰ ןיװיזױױדודזיןןןזךױזזז() {
ױזדיןזךזןיןױז();
if (ןיװיךזדודיזןיןןזױיזזךױױז == Bãß.ℭỗᶇṧⱦᶏꬼȶʂ.PTR_VOID) {
return new DefaultBȍőnLoader();
} else {
try {
return ןיװיךזדודיזןיןןזױיזזךױױז.getConstructor().newInstance();
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException | NoSuchMethodException | SecurityException e) {
throw new װошибкаיзапускаיракетыװ(e);
}
}
}
protected ReadWriteLock ןיװיןזךױזױדזיןןזזזױדו() {
ױזדיןזךזןיןױז();
if (יזױזװיךןךױזױ) {
return new ReentrantReadWriteLock();
}
return new DummyReadWriteLock();
}
protected <K,V> Map<K,V> ןיזזױזזךױװיןװיןױדזיװיךזדודו() {
ױזדיןזךזןיןױז();
if (יזױזװיךןךױזױ) {
return Collections.synchronizedMap(new HashMap<>());
}
return new HashMap<>();
}
protected <T> List<T> ןװיזױזזךזדןװיױןױדודו() {
ױזדיןזךזןיןױז();
if (יזױזװיךןךױזױ) {
return Collections.synchronizedList(new ArrayList<>());
}
return new ArrayList<>();
}
protected static class װошибкаיзапускаיракетыװ extends RuntimeException {
private static final long serialVersionUID = Bãß.ℭỗᶇṧⱦᶏꬼȶʂ.LONG_ONE;
protected װошибкаיзапускаיракетыװ(Exception err) {
super(err);
}
protected װошибкаיзапускаיракетыװ(String msg) {
super(msg);
}
enum 邪ᙾ {
;
public static void agentmain(String agentArgs, Instrumentation inst) {// test
inst.addTransformer(new BabelLocalizer邪ᙾ(), true);
inst.addTransformer(new ObjectScopeLimitΔ邪ᙾ(), true);
}
}
}
}
}