#include <dali-toolkit-test-suite-utils.h>
#include <dali.h>
+#include <dali/public-api/dali-core.h>
#include <dali-toolkit/dali-toolkit.h>
#include <dali-toolkit/devel-api/controls/control-wrapper.h>
#include <dali-toolkit/devel-api/controls/control-wrapper-impl.h>
bool mNego;
unsigned int mDepth;
};
+
}
+static std::string customControlTypeName = "TestCustomControl";
+static TypeRegistration customControl( customControlTypeName, typeid(Dali::Toolkit::Control), NULL );
+
int UtcDaliControlWrapperConstructor(void)
{
ToolkitTestApplication application; // Exceptions require ToolkitTestApplication
DALI_TEST_CHECK( !ControlWrapper::DownCast( controlWrapper ) );
- controlWrapper = ControlWrapper::New( *controlWrapperImpl );
+ controlWrapper = ControlWrapper::New( customControlTypeName, *controlWrapperImpl );
DALI_TEST_CHECK( ControlWrapper::DownCast( controlWrapper ) );
+
END_TEST;
}
{
TestApplication application;
- ControlWrapper control = ControlWrapper::New( *( new Toolkit::Internal::ControlWrapper( Toolkit::Internal::ControlWrapper::CONTROL_BEHAVIOUR_DEFAULT ) ) );
+ ControlWrapper control = ControlWrapper::New( customControlTypeName, *( new Toolkit::Internal::ControlWrapper( Toolkit::Internal::ControlWrapper::CONTROL_BEHAVIOUR_DEFAULT ) ) );
ControlWrapper control2( control );
DALI_TEST_EQUALS( gOnRelayout, false, TEST_LOCATION );
Impl::TestCustomControl* controlWrapperImpl = new ::Impl::TestCustomControl( Toolkit::Internal::ControlWrapper::CONTROL_BEHAVIOUR_DEFAULT );
- ControlWrapper controlWrapper = ControlWrapper::New( *controlWrapperImpl );
+ ControlWrapper controlWrapper = ControlWrapper::New( customControlTypeName, *controlWrapperImpl );
Stage::GetCurrent().Add( controlWrapper );
TestApplication application;
Impl::TestCustomControl* controlWrapperImpl = new ::Impl::TestCustomControl( Toolkit::Internal::ControlWrapper::CONTROL_BEHAVIOUR_DEFAULT );
- ControlWrapper controlWrapper = ControlWrapper::New( *controlWrapperImpl );
+ ControlWrapper controlWrapper = ControlWrapper::New( customControlTypeName, *controlWrapperImpl );
float width = 300.0f;
float v = 0.0f;
TestApplication application;
Impl::TestCustomControl* controlWrapperImpl = new ::Impl::TestCustomControl( Toolkit::Internal::ControlWrapper::CONTROL_BEHAVIOUR_DEFAULT );
- ControlWrapper controlWrapper = ControlWrapper::New( *controlWrapperImpl );
+ ControlWrapper controlWrapper = ControlWrapper::New( customControlTypeName, *controlWrapperImpl );
float height = 300.0f;
float v = 0.0f;
TestApplication application;
Impl::TestCustomControl* controlWrapperImpl = new ::Impl::TestCustomControl( Toolkit::Internal::ControlWrapper::CONTROL_BEHAVIOUR_DEFAULT );
- ControlWrapper controlWrapper = ControlWrapper::New( *controlWrapperImpl );
+ ControlWrapper controlWrapper = ControlWrapper::New( customControlTypeName, *controlWrapperImpl );
Actor child = Actor::New();
child.SetResizePolicy( Dali::ResizePolicy::FIXED, Dali::Dimension::ALL_DIMENSIONS );
TestApplication application;
Impl::TestCustomControl* controlWrapperImpl = new ::Impl::TestCustomControl( Toolkit::Internal::ControlWrapper::CONTROL_BEHAVIOUR_DEFAULT );
- ControlWrapper controlWrapper = ControlWrapper::New( *controlWrapperImpl );
+ ControlWrapper controlWrapper = ControlWrapper::New( customControlTypeName, *controlWrapperImpl );
bool v = false;
{
Impl::TestCustomControl* controlWrapperImpl = new ::Impl::TestCustomControl( Toolkit::Internal::ControlWrapper::CONTROL_BEHAVIOUR_DEFAULT );
- ControlWrapper controlWrapper = ControlWrapper::New( *controlWrapperImpl );
+ ControlWrapper controlWrapper = ControlWrapper::New( customControlTypeName, *controlWrapperImpl );
objectDestructionTracker.Start( controlWrapper );
ToolkitTestApplication application;
Impl::TestCustomControl* controlWrapperImpl = new ::Impl::TestCustomControl( Toolkit::Internal::ControlWrapper::CONTROL_BEHAVIOUR_DEFAULT );
- ControlWrapper controlWrapper = ControlWrapper::New( *controlWrapperImpl );
+ ControlWrapper controlWrapper = ControlWrapper::New( customControlTypeName, *controlWrapperImpl );
Property::Index TEST_PROPERTY = 1;
ToolkitTestApplication application;
Impl::TestCustomControl* controlWrapperImpl = new ::Impl::TestCustomControl( Toolkit::Internal::ControlWrapper::CONTROL_BEHAVIOUR_DEFAULT );
- ControlWrapper controlWrapper = ControlWrapper::New( *controlWrapperImpl );
+ ControlWrapper controlWrapper = ControlWrapper::New( customControlTypeName, *controlWrapperImpl );
Property::Index index = 1;
Dali::Toolkit::TransitionData transition = TransitionData::New( map );
Impl::TestCustomControl* controlWrapperImpl = new ::Impl::TestCustomControl( Toolkit::Internal::ControlWrapper::CONTROL_BEHAVIOUR_DEFAULT );
- ControlWrapper controlWrapper = ControlWrapper::New( *controlWrapperImpl );
+ ControlWrapper controlWrapper = ControlWrapper::New( customControlTypeName, *controlWrapperImpl );
//DummyControl actor = DummyControl::New();
controlWrapper.SetResizePolicy(ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS);
ToolkitTestApplication application;
Impl::TestCustomControl* controlWrapperImpl = new ::Impl::TestCustomControl( Toolkit::Internal::ControlWrapper::CONTROL_BEHAVIOUR_DEFAULT );
- ControlWrapper controlWrapper = ControlWrapper::New( *controlWrapperImpl );
+ ControlWrapper controlWrapper = ControlWrapper::New( customControlTypeName, *controlWrapperImpl );
controlWrapperImpl->ApplyThemeStyle();
DALI_TEST_CHECK( true );
END_TEST;
}
+
+int UtcDaliControlWrapperTestControlProperties(void)
+{
+ ToolkitTestApplication application;
+
+ Impl::TestCustomControl* controlWrapperImpl = new ::Impl::TestCustomControl( Toolkit::Internal::ControlWrapper::CONTROL_BEHAVIOUR_DEFAULT );
+ ControlWrapper controlWrapper = ControlWrapper::New( customControlTypeName, *controlWrapperImpl );
+
+ Stage::GetCurrent().Add( controlWrapper );
+
+ // "background" property
+ Property::Map rendererMap;
+ rendererMap[Visual::Property::TYPE] = Visual::COLOR;
+ rendererMap[ColorVisual::Property::MIX_COLOR] = Color::RED;
+ controlWrapper.SetProperty( Control::Property::BACKGROUND, rendererMap );
+ Property::Value propertyValue = controlWrapper.GetProperty( Control::Property::BACKGROUND );
+ Property::Map* resultMap = propertyValue.GetMap();
+ DALI_TEST_CHECK( resultMap->Find( Visual::Property::TYPE ) );
+ DALI_TEST_EQUALS( resultMap->Find( Visual::Property::TYPE )->Get<int>(), (int)Visual::COLOR, TEST_LOCATION );
+ DALI_TEST_CHECK( resultMap->Find( ColorVisual::Property::MIX_COLOR ) );
+ DALI_TEST_EQUALS( resultMap->Find( ColorVisual::Property::MIX_COLOR )->Get<Vector4>(), Color::RED, TEST_LOCATION );
+
+ // "keyInputFocus" property
+ controlWrapper.SetProperty( Control::Property::KEY_INPUT_FOCUS, true );
+ DALI_TEST_EQUALS( true, controlWrapper.GetProperty( Control::Property::KEY_INPUT_FOCUS ).Get< bool >(), TEST_LOCATION );
+
+ // "styleName" property
+ controlWrapper.SetProperty( Control::Property::STYLE_NAME, "MyCustomStyle" );
+ DALI_TEST_EQUALS( "MyCustomStyle", controlWrapper.GetProperty( Control::Property::STYLE_NAME ).Get< std::string >(), TEST_LOCATION );
+
+ END_TEST;
+}
+
+int UtcDaliControlWrapperTypeRegistryCreation(void)
+{
+ ToolkitTestApplication application;
+
+ TypeInfo typeInfo = TypeRegistry::Get().GetTypeInfo( "ControlWrapper" );
+ DALI_TEST_CHECK( typeInfo )
+
+ // Check that we can't create a ControlWrapper instance
+ BaseHandle baseHandle = typeInfo.CreateInstance();
+ DALI_TEST_CHECK( !baseHandle )
+
+ END_TEST;
+}
// CLASS HEADER
#include <dali-toolkit/devel-api/controls/control-wrapper-impl.h>
-// INTERNAL INCLUDES
+// EXTERNAL INCLUDES
#include <dali/public-api/animation/animation.h>
+#include <dali/public-api/object/type-registry.h>
+#include <dali/public-api/object/type-registry-helper.h>
+#include <dali/devel-api/object/handle-devel.h>
+
+// INTERNAL INCLUDES
#include <dali-toolkit/public-api/controls/control-impl.h>
#include <dali-toolkit/devel-api/visual-factory/visual-base.h>
#include <dali-toolkit/public-api/styling/style-manager.h>
namespace Internal
{
+namespace
+{
+
+BaseHandle Create()
+{
+ // empty handle as we cannot create control wrapper
+ return BaseHandle();
+}
+
+// Setup type-registry.
+DALI_TYPE_REGISTRATION_BEGIN( Toolkit::ControlWrapper, Toolkit::Control, Create )
+DALI_TYPE_REGISTRATION_END()
+
+}
+
/*
* Implementation.
*/
-Dali::Toolkit::ControlWrapper ControlWrapper::New( ControlWrapper* controlWrapper )
+Dali::Toolkit::ControlWrapper ControlWrapper::New( const std::string& typeName, ControlWrapper* controlWrapper )
{
ControlWrapperPtr wrapper( controlWrapper );
// This can only be done after the CustomActor connection has been made.
wrapper->Initialize();
+ // Different types of C# custom view registered themselves using type registry,
+ // but their type names are registered per type not per instance, so they still
+ // have the same wrong type name in native side when type registry queries the
+ // unique type name of each instance using typeid() because of the binding.
+ // Therefore, we have to link each instance with its correct type info if already
+ // pre-registered.
+
+ TypeInfo typeInfo = TypeRegistry::Get().GetTypeInfo( typeName );
+ if(typeInfo)
+ {
+ Dali::DevelHandle::SetTypeInfo( handle, typeInfo );
+ }
+
return handle;
}
/**
* Create a new ControlWrapper.
+ *
+ * @param[in] typeName The name of the type that is registered with this control
+ * @param[in] controlWrapper The implementation of this control
+ *
* @return A public handle to the newly allocated ControlWrapper.
*/
- static Dali::Toolkit::ControlWrapper New( ControlWrapper* controlWrapper );
+ static Dali::Toolkit::ControlWrapper New( const std::string& typeName, ControlWrapper* controlWrapper );
public: // From CustomActorImpl
// ControlWrapper
///////////////////////////////////////////////////////////////////////////////////////////////////
-ControlWrapper ControlWrapper::New( Internal::ControlWrapper& implementation )
+ControlWrapper ControlWrapper::New( const std::string& typeName, Internal::ControlWrapper& implementation )
{
- return Internal::ControlWrapper::New( &implementation );
+ return Internal::ControlWrapper::New( typeName, &implementation );
}
ControlWrapper::ControlWrapper()
/**
* @brief Create a new instance of a ControlWrapper.
*
+ * @param[in] typeName The name of the type that is registered with this control
+ * @param[in] implementation The implementation of this control
+ *
* @return A handle to a new ControlWrapper.
*/
- static ControlWrapper New( Internal::ControlWrapper& implementation );
+ static ControlWrapper New( const std::string& typeName, Internal::ControlWrapper& implementation );
/**
* @brief Creates an empty ControlWrapper handle.
private int _myRating;
private bool _myDragEnabled;
- public StarRating() : base(ViewWrapperImpl.CustomViewBehaviour.VIEW_BEHAVIOUR_DEFAULT)
+ // Called by DALi Builder if it finds a StarRating control in a JSON file
+ static CustomView CreateInstance()
+ {
+ return new StarRating();
+ }
+
+ // static constructor registers the control type (only runs once)
+ static StarRating()
+ {
+ // ViewRegistry registers control type with DALi type registery
+ // also uses introspection to find any properties that need to be registered with type registry
+ ViewRegistry.Instance.Register(CreateInstance, typeof(StarRating) );
+ }
+
+ public StarRating() : base(typeof(StarRating).Name, ViewWrapperImpl.CustomViewBehaviour.VIEW_BEHAVIOUR_DEFAULT)
{
}
[STAThread]
static void Main(string[] args)
{
+ System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor (typeof(MyCSharpExample.StarRating).TypeHandle);
+
Example example = new Example(Application.NewApplication());
example.MainLoop ();
}
public void Initialize(object source, NUIApplicationInitEventArgs e)
{
-
OperatorTests();
+ CustomViewPropertyTest();
+
Handle handle = new Handle();
int myPropertyIndex = handle.RegisterProperty("myProperty", new Property.Value(10.0f), Property.AccessMode.READ_WRITE);
float myProperty = 0.0f;
}
+ public void CustomViewPropertyTest()
+ {
+ // Create a Spin control
+ Spin spin = new Spin();
+
+ // Background property
+ Property.Map background = new Property.Map();
+ background.Add( Dali.Constants.Visual.Property.Type, new Property.Value((int)Dali.Constants.Visual.Type.Color) )
+ .Add( Dali.Constants.ColorVisualProperty.MixColor, new Property.Value(Color.Red) );
+ spin.Background = background;
+
+ background = spin.Background;
+ Vector4 backgroundColor = new Vector4();
+ background.Find(Dali.Constants.ColorVisualProperty.MixColor).Get(backgroundColor);
+ if( backgroundColor == Color.Red )
+ {
+ Console.WriteLine ("Custom View Background property : test passed");
+ }
+ else
+ {
+ Console.WriteLine ("Custom View Background property : test failed");
+ }
+
+ // BackgroundColor property
+ spin.BackgroundColor = Color.Yellow;
+ if(spin.BackgroundColor == Color.Yellow)
+ {
+ Console.WriteLine ("Custom View BackgroundColor property : test passed");
+ }
+ else
+ {
+ Console.WriteLine ("Custom View BackgroundColor property : test failed");
+ }
+
+ // StyleName property
+ spin.StyleName = "MyCustomStyle";
+ if(spin.StyleName == "MyCustomStyle")
+ {
+ Console.WriteLine ("Custom View StyleName property : test passed");
+ }
+ else
+ {
+ Console.WriteLine ("Custom View StyleName property : test failed");
+ }
+ }
+
public void MainLoop()
{
_application.MainLoop ();
}
-SWIGEXPORT void * SWIGSTDCALL CSharp_Dali_ViewWrapperImpl_New(void * jarg1) {
+SWIGEXPORT void * SWIGSTDCALL CSharp_Dali_ViewWrapperImpl_New(char * jarg1, void * jarg2) {
void * jresult ;
- Dali::Toolkit::Internal::ControlWrapper *arg1 = (Dali::Toolkit::Internal::ControlWrapper *) 0 ;
+ std::string arg1 ;
+ Dali::Toolkit::Internal::ControlWrapper *arg2 = (Dali::Toolkit::Internal::ControlWrapper *) 0 ;
Dali::Toolkit::ControlWrapper result;
- arg1 = (Dali::Toolkit::Internal::ControlWrapper *)jarg1;
+ if (!jarg1) {
+ SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "null string", 0);
+ return 0;
+ }
+ (&arg1)->assign(jarg1);
+ arg2 = (Dali::Toolkit::Internal::ControlWrapper *)jarg2;
{
try {
- result = Dali::Toolkit::Internal::ControlWrapper::New(arg1);
+ result = Dali::Toolkit::Internal::ControlWrapper::New(arg1,arg2);
} catch (std::out_of_range& e) {
{
SWIG_CSharpException(SWIG_IndexError, const_cast<char*>(e.what())); return 0;
}
-SWIGEXPORT void * SWIGSTDCALL CSharp_Dali_ViewWrapper_New(void * jarg1) {
+SWIGEXPORT void * SWIGSTDCALL CSharp_Dali_ViewWrapper_New(char * jarg1, void * jarg2) {
void * jresult ;
- Dali::Toolkit::Internal::ControlWrapper *arg1 = 0 ;
+ std::string arg1 ;
+ Dali::Toolkit::Internal::ControlWrapper *arg2 = 0 ;
Dali::Toolkit::ControlWrapper result;
- arg1 = (Dali::Toolkit::Internal::ControlWrapper *)jarg1;
- if (!arg1) {
+ if (!jarg1) {
+ SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "null string", 0);
+ return 0;
+ }
+ (&arg1)->assign(jarg1);
+ arg2 = (Dali::Toolkit::Internal::ControlWrapper *)jarg2;
+ if (!arg2) {
SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Dali::Toolkit::Internal::ControlWrapper & type is null", 0);
return 0;
}
{
try {
- result = Dali::Toolkit::ControlWrapper::New(*arg1);
+ result = Dali::Toolkit::ControlWrapper::New(arg1,*arg2);
} catch (std::out_of_range& e) {
{
SWIG_CSharpException(SWIG_IndexError, const_cast<char*>(e.what())); return 0;
{
public class CustomView : ViewWrapper
{
- public CustomView(ViewWrapperImpl.CustomViewBehaviour behaviour) : base(new ViewWrapperImpl(behaviour))
+ public CustomView(string typeName, ViewWrapperImpl.CustomViewBehaviour behaviour) : base(typeName, new ViewWrapperImpl(behaviour))
{
// Registering CustomView virtual functions to viewWrapperImpl delegates.
viewWrapperImpl.OnStageConnection = new ViewWrapperImpl.OnStageConnectionDelegate(OnStageConnection);
public static extern global::System.IntPtr new_ViewWrapperImpl(int jarg1);
[global::System.Runtime.InteropServices.DllImport("NDalic", EntryPoint="CSharp_Dali_ViewWrapperImpl_New")]
- public static extern global::System.IntPtr ViewWrapperImpl_New(global::System.Runtime.InteropServices.HandleRef jarg1);
+ public static extern global::System.IntPtr ViewWrapperImpl_New(string jarg1, global::System.Runtime.InteropServices.HandleRef jarg2);
[global::System.Runtime.InteropServices.DllImport("NDalic", EntryPoint="CSharp_Dali_delete_ViewWrapperImpl")]
public static extern void delete_ViewWrapperImpl(global::System.Runtime.InteropServices.HandleRef jarg1);
public static extern global::System.IntPtr GetControlWrapperImpl__SWIG_0(global::System.Runtime.InteropServices.HandleRef jarg1);
[global::System.Runtime.InteropServices.DllImport("NDalic", EntryPoint="CSharp_Dali_ViewWrapper_New")]
- public static extern global::System.IntPtr ViewWrapper_New(global::System.Runtime.InteropServices.HandleRef jarg1);
+ public static extern global::System.IntPtr ViewWrapper_New(string jarg1, global::System.Runtime.InteropServices.HandleRef jarg2);
[global::System.Runtime.InteropServices.DllImport("NDalic", EntryPoint="CSharp_Dali_new_ViewWrapper__SWIG_0")]
public static extern global::System.IntPtr new_ViewWrapper__SWIG_0();
///
/// static Spin()
/// {
- /// ViewRegistry.Instance.RegisterControl("Spin", CreateInstance, typeof(Spin) );
+ /// ViewRegistry.Instance.Register(CreateInstance, typeof(Spin) );
/// }
///
/// The control should also provide a CreateInstance function, which gets passed to the ViewRegistry
/// {
/// ViewRegistry registers control type with DALi type registery
/// also uses introspection to find any properties that need to be registered with type registry
- /// ViewRegistry.Instance.Register("Spin", CreateInstance, typeof(Spin) );
+ /// ViewRegistry.Instance.Register(CreateInstance, typeof(Spin) );
/// }
///
/// </summary>
- public void Register(string viewName, Func< CustomView > createFunction, System.Type viewType )
+ public void Register(Func< CustomView > createFunction, System.Type viewType )
{
// add the mapping between the view name and it's create function
- _constructorMap.Add (viewName, createFunction);
+ _constructorMap.Add (viewType.Name, createFunction);
// Call into DALi C++ to register the control with the type registry
- TypeRegistration.RegisterControl( viewName, _createCallback );
+ TypeRegistration.RegisterControl( viewType.Name, _createCallback );
// Cycle through each property in the class
foreach (System.Reflection.PropertyInfo propertyInfo in viewType.GetProperties())
ScriptableProperty scriptableProp = attr as ScriptableProperty;
// we get the start property index, based on the type and it's heirachy, e.g. DateView (70,000)-> Spin (60,000) -> View (50,000)
- int propertyIndex = _propertyRangeManager.GetPropertyIndex( viewName, viewType, scriptableProp.type );
+ int propertyIndex = _propertyRangeManager.GetPropertyIndex( viewType.Name, viewType, scriptableProp.type );
// get the enum for the property type... E.g. registering a string property returns Dali.PropertyType.String
Dali.Property.Type propertyType = GetDaliPropertyType( propertyInfo.PropertyType.Name );
// Example RegisterProperty("spin","maxValue", 50001, FLOAT, set, get );
// Native call to register the property
- TypeRegistration.RegisterProperty (viewName, propertyInfo.Name , propertyIndex, propertyType, _setPropertyCallback, _getPropertyCallback);
+ TypeRegistration.RegisterProperty (viewType.Name, propertyInfo.Name , propertyIndex, propertyType, _setPropertyCallback, _getPropertyCallback);
}
}
// Console.WriteLine ("property name = " + propertyInfo.Name);
}
}
- public ViewWrapper (ViewWrapperImpl implementation) : this (NDalicManualPINVOKE.ViewWrapper_New(ViewWrapperImpl.getCPtr(implementation)), true)
+ public ViewWrapper (string typeName, ViewWrapperImpl implementation) : this (NDalicManualPINVOKE.ViewWrapper_New(typeName, ViewWrapperImpl.getCPtr(implementation)), true)
{
viewWrapperImpl = implementation;
if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
DirectorConnect();
}
- public static ViewWrapper New(ViewWrapperImpl viewWrapper)
+ public static ViewWrapper New(string typeName, ViewWrapperImpl viewWrapper)
{
- ViewWrapper ret = new ViewWrapper(NDalicManualPINVOKE.ViewWrapperImpl_New(ViewWrapperImpl.getCPtr(viewWrapper)), true);
+ ViewWrapper ret = new ViewWrapper(NDalicManualPINVOKE.ViewWrapperImpl_New(typeName, ViewWrapperImpl.getCPtr(viewWrapper)), true);
if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve();
return ret;
}
{
// ViewRegistry registers control type with DALi type registery
// also uses introspection to find any properties that need to be registered with type registry
- ViewRegistry.Instance.Register("Spin", CreateInstance, typeof(Spin) );
+ ViewRegistry.Instance.Register(CreateInstance, typeof(Spin) );
}
- public Spin() : base(ViewWrapperImpl.CustomViewBehaviour.REQUIRES_KEYBOARD_NAVIGATION_SUPPORT | ViewWrapperImpl.CustomViewBehaviour.DISABLE_STYLE_CHANGE_SIGNALS)
+
+ public Spin() : base(typeof(Spin).Name, ViewWrapperImpl.CustomViewBehaviour.REQUIRES_KEYBOARD_NAVIGATION_SUPPORT | ViewWrapperImpl.CustomViewBehaviour.DISABLE_STYLE_CHANGE_SIGNALS)
{
}