Facebook Plugin-X Problems Android Eclipse Cocos2d-x 3.3rc1 - Please Help!

I’ve been trying to integrate Facebook into our Android project by following these instructions here: http://cocos2d-x.org/wiki/Facebook_integration_instruction_for_Cocos2d-x_and_Cocos2d-x-Lua_on_android

However I’m running into a number of problems for v 3.3rc1. The iOS version is working fine, but on Android and in Eclipse things don’t seem to be working.

First, step 3 which tells you to modify proj.android/jni/Android.mk results in an error that prevents the project from compiling at this line: $(call import-module,cocos2d/plugin/protocols/proj.android/jni)

Second, step 4 which tells you to use the line #include “PluginJniHelper.h” also results in a compile error. Eclipse isn’t able to find the correct header.

Third, step 8 which also asks you to modify proj.android/jni/Android.mk works but looks to attempt to do the exact same thing as step 3. Should we do step 8 and skip step 3?

Everything else runs fine but I can’t include FacebookAgent.h. Eclipse complains that it can’t find the header. If I use #include “plugin/publish/protocols/include/FacebookAgent.h” instead, it finds the header but can’t seem to find the implemented methods:

jni/…/…/Classes/somefile.cpp:153: error: undefined reference to ‘cocos2d::plugin::FacebookAgent::logout()’

Any help would really be appreciated!

I get a similar result

in step 3, I think it should be (note the …/ )

$(call import-module,…/cocos2d/plugin/protocols/proj.android/jni)

I agree that step 3 and 8 look the same

after this change, compilation is fine, but I get this error

/Volumes/Home/android/android-sdk-macosx/tools/ant/build.xml:659: /Volumes/Home/projects/wordbuild/cocos2d/plugin/plugins/facebook/proj.android/DependProject/src does not exist.

I was able to get the plugin working eventually. I had to dig through a lot of other threads and documentation online as well as figure somethings out on my own. Unfortunately, in my frenzy to get everything working I didn’t document my steps to get the plugins working.

My final Android.mk file contains these lines:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

$(call import-add-path,$(LOCAL_PATH)/…/…/cocos2d)
$(call import-add-path,$(LOCAL_PATH)/…/…/cocos2d/external)
$(call import-add-path,$(LOCAL_PATH)/…/…/cocos2d/cocos)
$(call import-add-path,$(LOCAL_PATH)/…/…/cocos2d/plugin/publish)

LOCAL_MODULE := cocos2dcpp_shared

LOCAL_MODULE_FILENAME := libcocos2dcpp

LOCAL_C_INCLUDES := $(LOCAL_PATH)/…/…/Classes

LOCAL_STATIC_LIBRARIES := cocos2dx_static
LOCAL_STATIC_LIBRARIES += PluginProtocolStatic

include $(BUILD_SHARED_LIBRARY)

$(call import-module,plugin/protocols/proj.android/jni)
$(call import-module,cocos)

The final step that I had to do was to import the FB_LibProject_complete project into my Eclipse workspace as well. It should be the depend project in your path. Make sure you import that into your workspace.

thanks…
yes, that wiki has instructions with typos… for example, in step 1

the XML “string” at end is missing /

hard to imagine that the cocos team publishes a wiki with broken instructions

I got further on the build… right now I get linking errors.
I am not using Ecplise but rather building from the command line, so I missed step 7, to add the jar files

do you know how can I specify the jar libraries on a command line build?

errors are

[javac] /Volumes/Home/projects/wordbuild/proj.android/src/org/cocos2dx/cpp/AppActivity.java:63: error: cannot find symbol
[javac] FacebookWrapper.onSaveInstanceState(outState);
[javac] ^

Sorry, like you were saying I used Eclipse so I’m not sure how to do that via the config files :confused: You might have better luck asking the question on GitHub.

After building the plugins , described in

I get this error

cocos run -p android -j 4 -m

Error: Activity class {org.cocos2dx.wordbuildfree/com.facebook.LoginActivity} does not exist.

one more build error

cocos run -p android -j 4 -m release

BUILD FAILED
/Volumes/Home/android/android-sdk-macosx/tools/ant/build.xml:601: The following error occurred while executing this line:

/Volumes/Home/android/android-sdk-macosx/tools/ant/build.xml:659: /Volumes/Home/projects/wordbuild/cocos2d/plugin/plugins/facebook/proj.android/DependProject/src does not exist.

this one is easy to fix, just create that folder…
just posting here hoping that the cocos team will fix this… somehow some script has to create that folder…

that said … I was able to build android with facebook plugin … from the command line… yay

when trying to run the app, it crashes

error log below

any bright ideas :smile:

01-31 23:57:51.188: E/AndroidRuntime(3344): FATAL EXCEPTION: main
01-31 23:57:51.188: E/AndroidRuntime(3344): Process: org.cocos2dx.wordbuildfree, PID: 3344
01-31 23:57:51.188: E/AndroidRuntime(3344): java.lang.NoClassDefFoundError: Failed resolution of: Lorg/cocos2dx/plugin/PluginWrapper;
01-31 23:57:51.188: E/AndroidRuntime(3344): at org.cocos2dx.cpp.AppActivity.onCreateView(AppActivity.java:43)
01-31 23:57:51.188: E/AndroidRuntime(3344): at org.cocos2dx.lib.Cocos2dxActivity.init(Cocos2dxActivity.java:329)
01-31 23:57:51.188: E/AndroidRuntime(3344): at org.cocos2dx.lib.Cocos2dxActivity.onCreate(Cocos2dxActivity.java:230)
01-31 23:57:51.188: E/AndroidRuntime(3344): at android.app.Activity.performCreate(Activity.java:5933)
01-31 23:57:51.188: E/AndroidRuntime(3344): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
01-31 23:57:51.188: E/AndroidRuntime(3344): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
01-31 23:57:51.188: E/AndroidRuntime(3344): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
01-31 23:57:51.188: E/AndroidRuntime(3344): at android.app.ActivityThread.access$800(ActivityThread.java:144)
01-31 23:57:51.188: E/AndroidRuntime(3344): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
01-31 23:57:51.188: E/AndroidRuntime(3344): at android.os.Handler.dispatchMessage(Handler.java:102)
01-31 23:57:51.188: E/AndroidRuntime(3344): at android.os.Looper.loop(Looper.java:135)
01-31 23:57:51.188: E/AndroidRuntime(3344): at android.app.ActivityThread.main(ActivityThread.java:5221)
01-31 23:57:51.188: E/AndroidRuntime(3344): at java.lang.reflect.Method.invoke(Native Method)
01-31 23:57:51.188: E/AndroidRuntime(3344): at java.lang.reflect.Method.invoke(Method.java:372)
01-31 23:57:51.188: E/AndroidRuntime(3344): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
01-31 23:57:51.188: E/AndroidRuntime(3344): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
01-31 23:57:51.188: E/AndroidRuntime(3344): Caused by: java.lang.ClassNotFoundException: Didn’t find class “org.cocos2dx.plugin.PluginWrapper” on path: DexPathList[[zip file “/data/app/org.cocos2dx.wordbuildfree-1/base.apk”],nativeLibraryDirectories=[/data/app/org.cocos2dx.wordbuildfree-1/lib/arm, /vendor/lib, /system/lib]]
01-31 23:57:51.188: E/AndroidRuntime(3344): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
01-31 23:57:51.188: E/AndroidRuntime(3344): at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
01-31 23:57:51.188: E/AndroidRuntime(3344): at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
01-31 23:57:51.188: E/AndroidRuntime(3344): … 16 more
01-31 23:57:51.188: E/AndroidRuntime(3344): Suppressed: java.lang.ClassNotFoundException: org.cocos2dx.plugin.PluginWrapper
01-31 23:57:51.188: E/AndroidRuntime(3344): at java.lang.Class.classForName(Native Method)
01-31 23:57:51.188: E/AndroidRuntime(3344): at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
01-31 23:57:51.188: E/AndroidRuntime(3344): at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
01-31 23:57:51.188: E/AndroidRuntime(3344): at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
01-31 23:57:51.188: E/AndroidRuntime(3344): … 17 more
01-31 23:57:51.188: E/AndroidRuntime(3344): Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available

I have the same problem with PluginWrapper, in general with all documentation in
http://cocos2d-x.org/wiki/Facebook_integration_instruction_for_Cocos2d-x_and_Cocos2d-x-Lua_on_android
Its maddening…

@jorgeriog I have successfully integrate Plugin-X Facebook for my project. I use ver 3.3 Final.
this is what I do :

  1. create new project using : cocos new “Your ProjectName” -p “Your Package Name” -l cpp -d “Your directory name”

  2. compile your android project.

  3. locate and run on terminal publish.sh in your project directory. for example : “sampleProject/cocos2d/plugin/tools/publish.sh”

  4. run gameDevGuide.sh on terminal in same directory.

  5. copy and paste your android project directory on the text field : for example “sampleProject/proj.android”.
    note : for those who dont know where to locate his android project just drag your proj.android folder on terminal. copy and paste folder location on gameDevGuide Text Field.

  6. Choose your plugin. for example Facebook. click Ok and close.

  7. import proj.android on eclipse.

  8. import Facebook Plugin on eclipse. for example : “sampleProject/cocos2d/plugin/plugins/facebook/proj.android/DependProject”.

  9. import Facebook plugin project as library.

  10. Create new string in string.xml. for example <string name="app_id">627454280762495</string>

  11. add the following code in AndroidManifest.xml :

<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/app_id" />
<activity android:name="com.facebook.LoginActivity" /> <provider android:authorities="com.facebook.app.NativeAppCallContentProvider641876029265874" android:name="com.facebook.NativeAppCallContentProvider" android:exported="true"/>

Change the number with your Facebook App ID.

  1. change plugin directory in “android.mk” with following code :
    $(call import-module,plugin/protocols/proj.android/jni)

  2. add the following code in main.cpp :


    #include “PluginJniHelper.h”

    void cocos_android_app_init (JNIEnv* env, jobject thiz) {

    AppDelegate pAppDelegate = new AppDelegate();
    JavaVM
    vm;
    env->GetJavaVM(&vm);
    PluginJniHelper::setJavaVM(vm);
    }

  3. modify AppActivity.java with the following code :


import org.cocos2dx.lib.Cocos2dxGLSurfaceView;
import org.cocos2dx.plugin.PluginWrapper;
import org.cocos2dx.plugin.FacebookWrapper;
import android.content.Intent;
import android.os.Bundle;

public class AppActivity extends Cocos2dxActivity {
@Override
public Cocos2dxGLSurfaceView onCreateView() {
Cocos2dxGLSurfaceView glSurfaceView = new Cocos2dxGLSurfaceView(this);
// TestCpp should create stencil buffer
glSurfaceView.setEGLConfigChooser(5, 6, 5, 0, 16, 8);

    PluginWrapper.init(this);
    PluginWrapper.setGLSurfaceView(glSurfaceView);
    FacebookWrapper.onCreate(this);
    return glSurfaceView;
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if(!PluginWrapper.onActivityResult(requestCode, resultCode, data))
    {
        super.onActivityResult(requestCode, resultCode, data);
    }
    FacebookWrapper.onAcitivityResult(requestCode, resultCode, data);
}

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    FacebookWrapper.onSaveInstanceState(outState);
}

}
15. Please dont use Cocos Console for compilation. I dont know why but it seem cocos console cant detect package org.cocos2dx.plugin. If you use cocos console you’ll find this error: “package org.cocos2dx.plugin does not exist”

Please use the old method, compile the project using “build_native.py” and run the project through eclipse.
for those who still failed, please ask me anytime.

Thank you

Thanks so much for the instructions:

on step4 , the script requires gawk, and it has been a challenge to find a gawk binary for the Mac

./gameDevGuide.sh
gawk is required, PLZ install it first.

[EDIT]
Not really a challenge
https://www.macports.org/
sudo port install gawk

For gawk, just download from this site :
http://rudix.org/packages/gawk.html

Also, please change the Title as SOLVED so the other can find this useful.

not exactly SOLVED for me yet :smile:

let’s see

  1. run gameDevGuide.sh on terminal in same directory.

it seems that this is just an automated script to do the changes explained in the docs, here

http://www.cocos2d-x.org/wiki/Plugin-X_Integration_Guide_for_Android

the same changes can be made manually, me I prefer to do the changes manually because I like to know what I am doing

more important , running that script , introduced this line

#$(call import-module,protocols/android)

and this makes compilation fail

so I replaced with

$(call import-module,plugin/protocols/proj.android/jni)

when I run the app in Eclipse it starts (a progress) , but when I try to run the facebook plugin code, it errors with the message

02-04 22:27:13.096: D/PluginFactory(12960): Can’t find java class org/cocos2dx/plugin/UserFacebook
02-04 22:27:13.096: A/libc(12960): Fatal signal 11 (SIGSEGV), code 1, fault addr 0x4 in tid 12977 (GLThread 2268)

the reason is probably I missed step 9

import Facebook plugin project as library.

Could you please post instructions how to do this? Like a menu sequence ? Thanks

on Step 9, right click your project and goto properties.

add facebook plugin as library.

yes, thanks
I still have errors after that…probably I missed something , I’ll try to redo everything :smile:

02-05 00:28:49.090: D/PluginFactory(15752): Java class name of plugin UserFacebook is : org/cocos2dx/plugin/UserFacebook
02-05 00:28:49.091: I/PluginWrapper(15752): class name : ----org/cocos2dx/plugin/UserFacebook----
02-05 00:28:49.098: W/System.err(15752): java.lang.reflect.InvocationTargetException
02-05 00:28:49.099: W/System.err(15752): at java.lang.reflect.Constructor.newInstance(Native Method)
02-05 00:28:49.099: W/System.err(15752): at java.lang.reflect.Constructor.newInstance(Constructor.java:288)
02-05 00:28:49.099: W/System.err(15752): at org.cocos2dx.plugin.PluginWrapper.initPlugin(PluginWrapper.java:125)
02-05 00:28:49.099: W/System.err(15752): at org.cocos2dx.lib.Cocos2dxRenderer.nativeTouchesEnd(Native Method)
02-05 00:28:49.099: W/System.err(15752): at org.cocos2dx.lib.Cocos2dxRenderer.handleActionUp(Cocos2dxRenderer.java:130)
02-05 00:28:49.099: W/System.err(15752): at org.cocos2dx.lib.Cocos2dxGLSurfaceView$9.run(Cocos2dxGLSurfaceView.java:257)
02-05 00:28:49.099: W/System.err(15752): at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1462)
02-05 00:28:49.099: W/System.err(15752): at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1239)
02-05 00:28:49.099: W/System.err(15752): Caused by: java.lang.NullPointerException: Argument ‘applicationId’ cannot be null
02-05 00:28:49.099: W/System.err(15752): at com.facebook.internal.Validate.notNull(Validate.java:29)
02-05 00:28:49.100: W/System.err(15752): at com.facebook.Session.(Session.java:281)
02-05 00:28:49.100: W/System.err(15752): at com.facebook.Session.(Session.java:266)
02-05 00:28:49.100: W/System.err(15752): at org.cocos2dx.plugin.UserFacebook.(UserFacebook.java:92)
02-05 00:28:49.100: W/System.err(15752): … 8 more
02-05 00:28:49.100: D/PluginFactory(15752): Can’t find java class org/cocos2dx/plugin/UserFacebook
02-05 00:28:49.100: A/libc(15752): Fatal signal 11 (SIGSEGV), code 1, fault addr 0x4 in tid 15770 (GLThread 2559)

I have no problem with the following instruction I mentioned above. Maybe you miss something.
I have tried the manual method but its too complicated, so I use gameDevGuide for simplicity.
Maybe you can use the auto method.

Hi everyone,
my code got those error, how can i fix it ?

02-10 21:23:39.930: W/dalvikvm(13744): threadid=1: thread exiting with uncaught exception (group=0x40c9b498)
02-10 21:23:39.930: E/AndroidRuntime(13744): FATAL EXCEPTION: main
02-10 21:23:39.930: E/AndroidRuntime(13744): java.lang.RuntimeException: Unable to get provider com.facebook.NativeAppCallContentProvider: java.lang.ClassNotFoundException: com.facebook.NativeAppCallContentProvider
02-10 21:23:39.930: E/AndroidRuntime(13744): 	at android.app.ActivityThread.installProvider(ActivityThread.java:4646)
02-10 21:23:39.930: E/AndroidRuntime(13744): 	at android.app.ActivityThread.installContentProviders(ActivityThread.java:4273)
02-10 21:23:39.930: E/AndroidRuntime(13744): 	at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4215)
02-10 21:23:39.930: E/AndroidRuntime(13744): 	at android.app.ActivityThread.access$1300(ActivityThread.java:138)
02-10 21:23:39.930: E/AndroidRuntime(13744): 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1263)
02-10 21:23:39.930: E/AndroidRuntime(13744): 	at android.os.Handler.dispatchMessage(Handler.java:99)
02-10 21:23:39.930: E/AndroidRuntime(13744): 	at android.os.Looper.loop(Looper.java:137)
02-10 21:23:39.930: E/AndroidRuntime(13744): 	at android.app.ActivityThread.main(ActivityThread.java:4845)
02-10 21:23:39.930: E/AndroidRuntime(13744): 	at java.lang.reflect.Method.invokeNative(Native Method)
02-10 21:23:39.930: E/AndroidRuntime(13744): 	at java.lang.reflect.Method.invoke(Method.java:511)
02-10 21:23:39.930: E/AndroidRuntime(13744): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
02-10 21:23:39.930: E/AndroidRuntime(13744): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556)
02-10 21:23:39.930: E/AndroidRuntime(13744): 	at dalvik.system.NativeStart.main(Native Method)
02-10 21:23:39.930: E/AndroidRuntime(13744): Caused by: java.lang.ClassNotFoundException: com.facebook.NativeAppCallContentProvider
02-10 21:23:39.930: E/AndroidRuntime(13744): 	at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:61)
02-10 21:23:39.930: E/AndroidRuntime(13744): 	at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
02-10 21:23:39.930: E/AndroidRuntime(13744): 	at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
02-10 21:23:39.930: E/AndroidRuntime(13744): 	at android.app.ActivityThread.installProvider(ActivityThread.java:4631)
02-10 21:23:39.930: E/AndroidRuntime(13744): 	... 12 more

Do you follow my instruction step by step?

What I get from this log is that it doesn’t detect com.facebook.NativeAppCallContentProvider.
I dont know whats the problem.

Do you use “publish.sh” from plugin folder?
If you dont please use it, its easier than manual method. So many code must be included on multiple file.
I never success implement plugin using manual method.

Or have you added this on android.mk?
$(call import-module,plugin/protocols/proj.android/jni)

Facing same problem:

04-17 07:31:25.390: I/ActivityThread(758): Pub com.facebook.app.NativeAppCallContentProvider641876029265874: com.facebook.NativeAppCallContentProvider
04-17 07:31:25.390: D/AndroidRuntime(758): Shutting down VM
04-17 07:31:25.400: W/dalvikvm(758): threadid=1: thread exiting with uncaught exception (group=0x409c01f8)
04-17 07:31:25.400: E/AndroidRuntime(758): FATAL EXCEPTION: main
04-17 07:31:25.400: E/AndroidRuntime(758): java.lang.RuntimeException: Unable to get provider com.facebook.NativeAppCallContentProvider: java.lang.ClassNotFoundException: com.facebook.NativeAppCallContentProvider
04-17 07:31:25.400: E/AndroidRuntime(758):     at android.app.ActivityThread.installProvider(ActivityThread.java:4240)
04-17 07:31:25.400: E/AndroidRuntime(758):     at android.app.ActivityThread.installContentProviders(ActivityThread.java:3992)
04-17 07:31:25.400: E/AndroidRuntime(758):     at android.app.ActivityThread.handleBindApplication(ActivityThread.java:3946)
04-17 07:31:25.400: E/AndroidRuntime(758):     at android.app.ActivityThread.access$1300(ActivityThread.java:123)
04-17 07:31:25.400: E/AndroidRuntime(758):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1185)
04-17 07:31:25.400: E/AndroidRuntime(758):     at android.os.Handler.dispatchMessage(Handler.java:99)
04-17 07:31:25.400: E/AndroidRuntime(758):     at android.os.Looper.loop(Looper.java:137)
04-17 07:31:25.400: E/AndroidRuntime(758):     at android.app.ActivityThread.main(ActivityThread.java:4424)
04-17 07:31:25.400: E/AndroidRuntime(758):     at java.lang.reflect.Method.invokeNative(Native Method)
04-17 07:31:25.400: E/AndroidRuntime(758):     at java.lang.reflect.Method.invoke(Method.java:511)
04-17 07:31:25.400: E/AndroidRuntime(758):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
04-17 07:31:25.400: E/AndroidRuntime(758):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
04-17 07:31:25.400: E/AndroidRuntime(758):     at dalvik.system.NativeStart.main(Native Method)
04-17 07:31:25.400: E/AndroidRuntime(758): Caused by: java.lang.ClassNotFoundException: com.facebook.NativeAppCallContentProvider
04-17 07:31:25.400: E/AndroidRuntime(758):     at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:61)
04-17 07:31:25.400: E/AndroidRuntime(758):     at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
04-17 07:31:25.400: E/AndroidRuntime(758):     at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
04-17 07:31:25.400: E/AndroidRuntime(758):     at android.app.ActivityThread.installProvider(ActivityThread.java:4225)
04-17 07:31:25.400: E/AndroidRuntime(758):     ... 12 more
04-17 07:31:25.660: I/dalvikvm(758): threadid=3: reacting to signal 3
04-17 07:31:25.670: I/dalvikvm(758): Wrote stack traces to '/data/anr/traces.txt'
04-17 07:31:26.180: I/dalvikvm(758): threadid=3: reacting to signal 3
04-17 07:31:26.190: I/dalvikvm(758): Wrote stack traces to '/data/anr/traces.txt'

Windows 8.1 x64, cocos2d-x 3.4.

Plugin-X really works? Every link i found about plugin-x seem to be very old or something doesn’t work well.

Anyone tried calling facebook API directly from C++ using JNIHelpers?

There were a lot of bugs in both the iOS and Android implementation of Plugin-X and their Facebook plugin. If I were to do it over again, I would definitely start from scratch. I think the only part of the plugin-x framework that has been beneficial is the JNI glue code and helpers written that pass data structures semi-transparently from native to Java and Obj-C.

I also ended up pretty much rewriting the entirety of the Android Google Play IAP code and reworking most of the flow of the iOS IAP code.