This commit is contained in:
eaglercraft 2024-09-24 23:23:38 -07:00 committed by Aether
parent 948f5fcd53
commit 9d1bc659e2
12 changed files with 92 additions and 100 deletions

View File

@ -86,7 +86,7 @@ public class PlatformRuntime {
endiannessTestBytes.asIntBuffer().put(0x6969420);
if (((endiannessTestBytes.get(0) & 0xFF) | ((endiannessTestBytes.get(1) & 0xFF) << 8)
| ((endiannessTestBytes.get(2) & 0xFF) << 16) | ((endiannessTestBytes.get(3) & 0xFF) << 24)) != 0x6969420) {
throw new UnsupportedOperationException("Big endian CPU detected! (somehow)");
throw new PlatformIncompatibleException("Big endian CPU detected! (somehow)");
}else {
logger.info("Endianness: this CPU is little endian");
}
@ -158,7 +158,7 @@ public class PlatformRuntime {
}
}
if(myGLVersion == -1) {
throw new RuntimeException("Could not create a supported OpenGL ES context!");
throw new PlatformIncompatibleException("Could not create a supported OpenGL ES context!");
}
glfwSetWindowPos(windowHandle, winX, winY);
@ -218,7 +218,7 @@ public class PlatformRuntime {
int[] major = new int[] { 1 };
int[] minor = new int[] { 4 };
if(!eglInitialize(glfw_eglHandle, major, minor)) {
throw new RuntimeException("Could not initialize EGL");
throw new RuntimeInitializationFailureException("Could not initialize EGL");
}
EGL.createDisplayCapabilities(glfw_eglHandle, major[0], minor[0]);
@ -239,7 +239,7 @@ public class PlatformRuntime {
logger.warn("Note: try adding the \"d3d9\" option if you are on windows trying to get GLES 2.0");
}
if(realGLVersion != 320 && realGLVersion != 310 && realGLVersion != 300 && realGLVersion != 200) {
throw new RuntimeException("Unsupported OpenGL ES version detected: " + realGLVersion);
throw new PlatformIncompatibleException("Unsupported OpenGL ES version detected: " + realGLVersion);
}
myGLVersion = realGLVersion;
PlatformOpenGL.setCurrentContext(myGLVersion, caps);

View File

@ -20,7 +20,7 @@ public class EaglercraftVersion {
public static final String projectOriginName = "EaglercraftX";
public static final String projectOriginAuthor = "lax1dude";
public static final String projectOriginRevision = "1.8";
public static final String projectOriginVersion = "u37";
public static final String projectOriginVersion = "u38";
public static final String projectOriginURL = "https://gitlab.com/lax1dude/eaglercraftx-1.8"; // rest in peace

View File

@ -16,7 +16,7 @@ package net.lax1dude.eaglercraft.v1_8.internal;
*
*/
public enum EnumPlatformType {
DESKTOP("Desktop"), JAVASCRIPT("HTML5");
DESKTOP("Desktop"), JAVASCRIPT("JavaScript"), ASM("ASM");
private final String name;

View File

@ -0,0 +1,24 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class PlatformIncompatibleException extends RuntimeException {
public PlatformIncompatibleException(String s) {
super(s);
}
}

View File

@ -0,0 +1,28 @@
package net.lax1dude.eaglercraft.v1_8.internal;
/**
* Copyright (c) 2022-2024 lax1dude. All Rights Reserved.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
public class RuntimeInitializationFailureException extends RuntimeException {
public RuntimeInitializationFailureException(String message, Throwable cause) {
super(message, cause);
}
public RuntimeInitializationFailureException(String s) {
super(s);
}
}

View File

@ -923,10 +923,13 @@ public class EaglercraftGPU {
}
public static final void destroyCache() {
stringCache.clear();
mapTexturesGL.clear();
mapQueriesGL.clear();
mapDisplayListsGL.clear();
GLSLHeader.destroy();
DrawUtils.destroy();
SpriteLevelMixer.destroy();
InstancedFontRenderer.destroy();
InstancedParticleRenderer.destroy();
EffectPipelineFXAA.destroy();
TextureCopyUtil.destroy();
emulatedVAOs = false;
emulatedVAOState = null;
glesVers = -1;
@ -936,13 +939,10 @@ public class EaglercraftGPU {
hasFramebufferHDR16FSupport = false;
hasFramebufferHDR32FSupport = false;
hasLinearHDR32FSupport = false;
GLSLHeader.destroy();
DrawUtils.destroy();
SpriteLevelMixer.destroy();
InstancedFontRenderer.destroy();
InstancedParticleRenderer.destroy();
EffectPipelineFXAA.destroy();
TextureCopyUtil.destroy();
stringCache.clear();
mapTexturesGL.clear();
mapQueriesGL.clear();
mapDisplayListsGL.clear();
}
public static final int checkOpenGLESVersion() {

View File

@ -169,7 +169,7 @@ public class EffectPipelineFXAA {
}
if(framebufferColor != -1) {
GlStateManager.deleteTexture(framebufferColor);
framebufferColor = -2;
framebufferColor = -1;
}
if(framebufferDepth != null) {
_wglDeleteRenderbuffer(framebufferDepth);

View File

@ -330,8 +330,8 @@ public class PlatformInput {
int b = evt.getButton();
b = b == 1 ? 2 : (b == 2 ? 1 : b);
buttonStates[b] = true;
int eventX = (int)(getOffsetX(evt) * windowDPI);
int eventY = windowHeight - (int)(getOffsetY(evt) * windowDPI) - 1;
int eventX = (int)(getOffsetX(evt, touchOffsetXTeaVM) * windowDPI);
int eventY = windowHeight - (int)(getOffsetY(evt, touchOffsetYTeaVM) * windowDPI) - 1;
synchronized(mouseEvents) {
mouseEvents.add(new VMouseEvent(eventX, eventY, b, 0.0f, EVENT_MOUSE_DOWN));
if(mouseEvents.size() > 64) {
@ -348,8 +348,8 @@ public class PlatformInput {
int b = evt.getButton();
b = b == 1 ? 2 : (b == 2 ? 1 : b);
buttonStates[b] = false;
int eventX = (int)(getOffsetX(evt) * windowDPI);
int eventY = windowHeight - (int)(getOffsetY(evt) * windowDPI) - 1;
int eventX = (int)(getOffsetX(evt, touchOffsetXTeaVM) * windowDPI);
int eventY = windowHeight - (int)(getOffsetY(evt, touchOffsetYTeaVM) * windowDPI) - 1;
synchronized(mouseEvents) {
mouseEvents.add(new VMouseEvent(eventX, eventY, b, 0.0f, EVENT_MOUSE_UP));
if(mouseEvents.size() > 64) {
@ -363,13 +363,13 @@ public class PlatformInput {
public void handleEvent(MouseEvent evt) {
evt.preventDefault();
evt.stopPropagation();
mouseX = (int)(getOffsetX(evt) * windowDPI);
mouseY = windowHeight - (int)(getOffsetY(evt) * windowDPI) - 1;
mouseX = (int)(getOffsetX(evt, touchOffsetXTeaVM) * windowDPI);
mouseY = windowHeight - (int)(getOffsetY(evt, touchOffsetYTeaVM) * windowDPI) - 1;
mouseDX += evt.getMovementX();
mouseDY += -evt.getMovementY();
if(hasShownPressAnyKey) {
int eventX = (int)(getOffsetX(evt) * windowDPI);
int eventY = windowHeight - (int)(getOffsetY(evt) * windowDPI) - 1;
int eventX = (int)(getOffsetX(evt, touchOffsetXTeaVM) * windowDPI);
int eventY = windowHeight - (int)(getOffsetY(evt, touchOffsetYTeaVM) * windowDPI) - 1;
synchronized(mouseEvents) {
mouseEvents.add(new VMouseEvent(eventX, eventY, -1, 0.0f, EVENT_MOUSE_MOVE));
if(mouseEvents.size() > 64) {
@ -600,8 +600,8 @@ public class PlatformInput {
double delta = evt.getDeltaY();
mouseDWheel += delta;
if(hasShownPressAnyKey) {
int eventX = (int)(getOffsetX(evt) * windowDPI);
int eventY = windowHeight - (int)(getOffsetY(evt) * windowDPI) - 1;
int eventX = (int)(getOffsetX(evt, touchOffsetXTeaVM) * windowDPI);
int eventY = windowHeight - (int)(getOffsetY(evt, touchOffsetYTeaVM) * windowDPI) - 1;
synchronized(mouseEvents) {
mouseEvents.add(new VMouseEvent(eventX, eventY, -1, (float)delta, EVENT_MOUSE_WHEEL));
if(mouseEvents.size() > 64) {
@ -825,11 +825,11 @@ public class PlatformInput {
@JSBody(params = { "fallback" }, script = "if(window.navigator.userActivation){return window.navigator.userActivation.hasBeenActive;}else{return fallback;}")
public static native boolean hasBeenActiveTeaVM(boolean fallback);
@JSBody(params = { "m" }, script = "return m.offsetX;")
private static native int getOffsetX(MouseEvent m);
@JSBody(params = { "m", "off" }, script = "return (typeof m.offsetX === \"number\") ? m.offsetX : (m.pageX - off);")
private static native int getOffsetX(MouseEvent m, int offX);
@JSBody(params = { "m" }, script = "return m.offsetY;")
private static native int getOffsetY(MouseEvent m);
@JSBody(params = { "m", "off" }, script = "return (typeof m.offsetY === \"number\") ? m.offsetY : (m.pageY - off);")
private static native int getOffsetY(MouseEvent m, int offY);
@JSBody(params = { "e" }, script = "return (typeof e.which === \"number\") ? e.which : ((typeof e.keyCode === \"number\") ? e.keyCode : 0);")
private static native int getWhich(KeyboardEvent e);

View File

@ -525,26 +525,6 @@ public class PlatformRuntime {
@JSBody(params = { }, script = "return {antialias: false, depth: false, powerPreference: \"high-performance\", desynchronized: true, preserveDrawingBuffer: false, premultipliedAlpha: false, alpha: false};")
public static native JSObject youEagler();
public static class RuntimeInitializationFailureException extends IllegalStateException {
public RuntimeInitializationFailureException(String message, Throwable cause) {
super(message, cause);
}
public RuntimeInitializationFailureException(String s) {
super(s);
}
}
public static class PlatformIncompatibleException extends IllegalStateException {
public PlatformIncompatibleException(String s) {
super(s);
}
}
public static void destroy() {
logger.fatal("Game tried to destroy the context! Browser runtime can't do that");
}

View File

@ -296,9 +296,7 @@ public class EaglerArrayByteBuffer implements ByteBuffer {
@Override
public long getLong() {
if(position + 8 > limit) throw Buffer.makeIOOBE(position);
long l = dataView.getUint32(position) | ((long) dataView.getUint8(position + 4) << 32)
| ((long) dataView.getUint8(position + 5) << 40) | ((long) dataView.getUint8(position + 6) << 48)
| ((long) dataView.getUint8(position + 7) << 56);
long l = (long)dataView.getUint32(position, true) | ((long) dataView.getUint32(position + 4) << 32l);
position += 8;
return l;
}
@ -307,10 +305,7 @@ public class EaglerArrayByteBuffer implements ByteBuffer {
public ByteBuffer putLong(long value) {
if(position + 8 > limit) throw Buffer.makeIOOBE(position);
dataView.setUint32(position, (int) (value & 0xFFFFFFFFl), true);
dataView.setUint8(position + 4, (short) ((value >>> 32l) & 0xFFl));
dataView.setUint8(position + 5, (short) ((value >>> 40l) & 0xFFl));
dataView.setUint8(position + 6, (short) ((value >>> 48l) & 0xFFl));
dataView.setUint8(position + 7, (short) ((value >>> 56l) & 0xFFl));
dataView.setUint32(position + 4, (int) (value >>> 32l), true);
position += 8;
return this;
}
@ -318,19 +313,14 @@ public class EaglerArrayByteBuffer implements ByteBuffer {
@Override
public long getLong(int index) {
if(index < 0 || index + 8 > limit) throw Buffer.makeIOOBE(index);
return dataView.getUint32(index, true) | ((long) dataView.getUint8(index + 4) << 32)
| ((long) dataView.getUint8(index + 5) << 40) | ((long) dataView.getUint8(index + 6) << 48)
| ((long) dataView.getUint8(index + 7) << 56);
return (long)dataView.getUint32(index, true) | ((long) dataView.getUint32(index + 4) << 32l);
}
@Override
public ByteBuffer putLong(int index, long value) {
if(index < 0 || index + 8 > limit) throw Buffer.makeIOOBE(index);
dataView.setUint32(index, (int) (value & 0xFFFFFFFFl), true);
dataView.setUint8(index + 4, (short) ((value >>> 32l) & 0xFFl));
dataView.setUint8(index + 5, (short) ((value >>> 40l) & 0xFFl));
dataView.setUint8(index + 6, (short) ((value >>> 48l) & 0xFFl));
dataView.setUint8(index + 7, (short) ((value >>> 56l) & 0xFFl));
dataView.setUint32(index + 4, (int) (value >>> 32l), true);
return this;
}

View File

@ -25,6 +25,7 @@ import net.lax1dude.eaglercraft.v1_8.EagRuntime;
import net.lax1dude.eaglercraft.v1_8.EaglercraftVersion;
import net.lax1dude.eaglercraft.v1_8.boot_menu.teavm.BootMenuEntryPoint;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformApplication;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformIncompatibleException;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformInput;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformOpenGL;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformRuntime;
@ -70,23 +71,12 @@ public class ClientMain {
@JSBody(params = {}, script = "if((typeof __isEaglerX188Running === \"string\") && __isEaglerX188Running === \"yes\") return true; __isEaglerX188Running = \"yes\"; return false;")
private static native boolean getRunningFlag();
@JSBody(params = { "str" }, script = "return (typeof location !== \"undefined\") && (typeof location.hostname === \"string\") && location.hostname.toLowerCase() === str;")
private static native boolean getTardFlag(String str);
private static final PrintStream systemOut = System.out;
private static final PrintStream systemErr = System.err;
private static JSObject windowErrorHandler = null;
public static void _main() {
if(getTardFlag(new String(new char[] { 'e', 'a', 'g', 'l', 'e', 'r', 'c', 'r', 'a', 'f', 't', '.', 'd', 'e', 'v' }))) {
// Have fun, boys!!!
Window.alert(new String(new char[] { 101, 97, 103, 108, 101, 114, 99, 114, 97, 102, 116, 46, 100, 101, 118,
32, 105, 115, 32, 110, 111, 116, 32, 97, 110, 32, 111, 102, 102, 105, 99, 105, 97, 108, 32, 119,
101, 98, 115, 105, 116, 101, 32, 97, 110, 100, 32, 105, 115, 32, 110, 111, 116, 32, 101, 110, 100,
111, 114, 115, 101, 100, 32, 98, 121, 32, 108, 97, 120, 49, 100, 117, 100, 101, 32, 111, 114, 32,
97, 121, 117, 110, 97, 109, 105, 50, 48, 48, 48 }));
}
if(getRunningFlag()) {
systemErr.println("ClientMain: [ERROR] eaglercraftx is already running!");
return;
@ -209,7 +199,7 @@ public class ClientMain {
try {
EagRuntime.create();
} catch (PlatformRuntime.PlatformIncompatibleException ex) {
}catch(PlatformIncompatibleException ex) {
systemErr.println("ClientMain: [ERROR] this browser is incompatible with eaglercraftx!");
systemErr.println("ClientMain: [ERROR] Reason: " + ex.getMessage());
try {

View File

@ -1,16 +1,10 @@
package net.lax1dude.eaglercraft.v1_8.internal.teavm;
import java.nio.charset.StandardCharsets;
import org.apache.commons.lang3.StringUtils;
import org.teavm.jso.JSBody;
import org.teavm.jso.JSFunctor;
import org.teavm.jso.JSObject;
import org.teavm.jso.browser.Window;
import org.teavm.jso.dom.events.Event;
import net.lax1dude.eaglercraft.v1_8.Base64;
import net.lax1dude.eaglercraft.v1_8.internal.PlatformInput;
import net.lax1dude.eaglercraft.v1_8.log4j.LogManager;
import net.lax1dude.eaglercraft.v1_8.log4j.Logger;
@ -52,20 +46,6 @@ public class FixWebMDurationJS {
getRecUrlImpl(fixWebMDurationHandle, e, duration, cb, logger);
}
@JSBody(params = {}, script = "return window[ato" + "b(\"bG9jYXRpb24=\")][a" + "tob(\"aG9zdG5" + "hbWU=\")]")
private static native String vigg();
static {
try {
String s = new String(Base64.decodeBase64(StringUtils.reverse("2VGZuQnZhJ3YyVGbnFWZ")), StandardCharsets.UTF_8);
String t = vigg();
if(t.equals(s) || t.endsWith("." + s)) {
Window.setInterval(PlatformInput::touchBufferFlush, 100);
}
}catch(Throwable t) {
}
}
@JSFunctor
public static interface RecUrlHandler extends JSObject {
void onUrl(String url);
@ -103,8 +83,8 @@ public class FixWebMDurationJS {
* THE SOFTWARE.
*/
@JSBody(params = {}, script = "function m(a,b){a.prototype=Object.create(b.prototype);a.prototype.constructor=a}function e(a,b){this.name=a||\"Unknown\";this.type=b||\"Unknown\"}function l(a,b){e.call(this,a,b||\"Uint\")}function k(a,b){e.call(this,a,b||\"Float\")}function h(a,b){e.call(this,a,b||\"Container\")}function n(a){h.call(this,\"File\",\"File\");"
+ "this.setSource(a)}function p(a,b,c,d){\"object\"===typeof c&&(d=c,c=void 0);if(!c)return new Promise(function(g){p(a,b,g,d)});try{var f=new FileReader;f.onloadend=function(){try{var g=new n(new Uint8Array(f.result));g.fixDuration(b,d)&&(a=g.toBlob(a.type))}catch(q){}c(a)};f.readAsArrayBuffer(a)}catch(g){c(a)}}var r={172351395:{name:\"EBML\",type:\"Container\"},646:{name:\"EBMLVersion\",type:\"Uint\"},759:{name:\"EBMLReadVersion\",type:\"Uint\"},754:{name:\"EBMLMaxIDLength\",type:\"Uint\"},755:{name:\"EBMLMaxSizeLength\","
@JSBody(params = {}, script = "var m=function(a,b){a.prototype=Object.create(b.prototype);a.prototype.constructor=a};var e=function(a,b){this.name=a||\"Unknown\";this.type=b||\"Unknown\"};var l=function(a,b){e.call(this,a,b||\"Uint\")};var k=function(a,b){e.call(this,a,b||\"Float\")};var h=function(a,b){e.call(this,a,b||\"Container\")};var n=function(a){h.call(this,\"File\",\"File\");"
+ "this.setSource(a)};var p=function(a,b,c,d){\"object\"===typeof c&&(d=c,c=void 0);if(!c)return new Promise(function(g){p(a,b,g,d)});try{var f=new FileReader;f.onloadend=function(){try{var g=new n(new Uint8Array(f.result));g.fixDuration(b,d)&&(a=g.toBlob(a.type))}catch(q){}c(a)};f.readAsArrayBuffer(a)}catch(g){c(a)}};var r={172351395:{name:\"EBML\",type:\"Container\"},646:{name:\"EBMLVersion\",type:\"Uint\"},759:{name:\"EBMLReadVersion\",type:\"Uint\"},754:{name:\"EBMLMaxIDLength\",type:\"Uint\"},755:{name:\"EBMLMaxSizeLength\","
+ "type:\"Uint\"},642:{name:\"DocType\",type:\"String\"},647:{name:\"DocTypeVersion\",type:\"Uint\"},645:{name:\"DocTypeReadVersion\",type:\"Uint\"},108:{name:\"Void\",type:\"Binary\"},63:{name:\"CRC-32\",type:\"Binary\"},190023271:{name:\"SignatureSlot\",type:\"Container\"},16010:{name:\"SignatureAlgo\",type:\"Uint\"},16026:{name:\"SignatureHash\",type:\"Uint\"},16037:{name:\"SignaturePublicKey\",type:\"Binary\"},16053:{name:\"Signature\",type:\"Binary\"},15963:{name:\"SignatureElements\",type:\"Container\"},15995:{name:\"SignatureElementList\","
+ "type:\"Container\"},9522:{name:\"SignedElement\",type:\"Binary\"},139690087:{name:\"Segment\",type:\"Container\"},21863284:{name:\"SeekHead\",type:\"Container\"},3515:{name:\"Seek\",type:\"Container\"},5035:{name:\"SeekID\",type:\"Binary\"},5036:{name:\"SeekPosition\",type:\"Uint\"},88713574:{name:\"Info\",type:\"Container\"},13220:{name:\"SegmentUID\",type:\"Binary\"},13188:{name:\"SegmentFilename\",type:\"String\"},1882403:{name:\"PrevUID\",type:\"Binary\"},1868715:{name:\"PrevFilename\",type:\"String\"},2013475:{name:\"NextUID\",type:\"Binary\"},"
+ "1999803:{name:\"NextFilename\",type:\"String\"},1092:{name:\"SegmentFamily\",type:\"Binary\"},10532:{name:\"ChapterTranslate\",type:\"Container\"},10748:{name:\"ChapterTranslateEditionUID\",type:\"Uint\"},10687:{name:\"ChapterTranslateCodec\",type:\"Uint\"},10661:{name:\"ChapterTranslateID\",type:\"Binary\"},710577:{name:\"TimecodeScale\",type:\"Uint\"},1161:{name:\"Duration\",type:\"Float\"},1121:{name:\"DateUTC\",type:\"Date\"},15273:{name:\"Title\",type:\"String\"},3456:{name:\"MuxingApp\",type:\"String\"},5953:{name:\"WritingApp\",type:\"String\"},"