EQ2Interface

EQ2Interface (https://www.eq2interface.com/forums/index.php)
-   UI Developer Discussion (https://www.eq2interface.com/forums/forumdisplay.php?f=3)
-   -   Why is Raz's AutoAttack timer code so crazy? (https://www.eq2interface.com/forums/showthread.php?t=13169)

dragowulf 08-01-2009 04:44 AM

Why is Raz's AutoAttack timer code so crazy?
 
I don't understand why Raz's code seems to be more complicated than it really should be, am I missing something? I made one of my own that's like 10kb or so with just a composite and a few OnShow/OnHide triggers and it performs beautifully...am I missing something?

gm9 08-01-2009 06:12 AM

:) and :D and :nana:

(and I have no idea, I think it was just his code evolution)

dragowulf 08-01-2009 09:32 AM

Quote:

Originally Posted by gm9 (Post 84987)
:) and :D and :nana:

(and I have no idea, I think it was just his code evolution)

Lol. I've had code evolution like that before, but usually when it gets out of hand I can't stand it and re-do it.

samejima 08-01-2009 11:48 AM

Pretty much though the problems people have with it are the dynamic data. I have a file that is nothing but progress bars and it runs into the same problems. (unless things have changed) Kind of ironic too!

EDIT: WOW WHY DOES IT HAVE A LITTLE ANGRY FACE THERE!!!

dragowulf 08-01-2009 12:35 PM

The only big problems that I see with it are when it is at 100% or 0% it is still visible. Because of this it requires a big workaround that doesn't even work completely.

samejima 08-01-2009 12:58 PM

I could probably make it WAY EASIER thinking about it. Gm9 pretty much hit it on the head though. I coded it from my original code, then dynamic data was added. Then after that it was changed a few times, at that point I could not be bothered to redo it every week.

dragowulf 08-01-2009 01:18 PM

I originally was going to clean up your code, but your code made my eyes bleed lol. Nonetheless I made one very similar to yours, but I started from scratch (I tried to use yours as a reference, but I couldn't) and tried to work out all the DynamicData problems with workarounds. You can take a look at the pretty simplified code if you want.

samejima 08-01-2009 01:48 PM

there is no workaround that I can think of, the problem is that it skips some times due to something with recovery time as far as I can tell.

speedycerv 08-01-2009 01:57 PM

Personally on windows 7 it has issues where it will stay 100% when auto attack is hitting/missing quite frequently, it is more stable on Vista for some reason. If you know why, and how to fix it, please help :)

Also ACT is set up to make a noise when auto hits, and on windows 7, it's randomly not doing it aswell. I'm thinking these issues in Win 7 are to do with write protected, since other programs seems to be having similar issues. But I'm not sure how to fix that.

dragowulf 08-01-2009 02:07 PM

I don't think it's just Windows 7. I'll do some more testing.

There needs to be at least some kind of OnEventFinished or something so we can get rid of some of these issues with progressbars. Or they can implement it w/in the data.

samejima 08-01-2009 03:23 PM

I was getting ready to patch some of the new stuff that got added! Though while I was doing that I saw this thread, updated it now. WAY less complicated, thanks for making me stop being lazy.

EDIT: I run windows xp still, I could reproduce it 80% of the time when I tested it last.

samejima 08-01-2009 07:05 PM

EDIT: T-T Hopefully not

dragowulf 08-01-2009 07:40 PM

I can't figure out what's wrong with my code. When I initially log on and do Ranged auto attack and then switch to Melee I can't see the Melee until pretty much the next encounter. Can anyone help find the problem please?
Code:

<?xml version="1.0" encoding="utf-8"?>
<Page eq2usescomwndcontrols="true" Location="255,557" MaximumSize="16384,50" MinimumSize="140,50" Name="AutoAttackTimer" PackLocation="center,bottom" ScrollExtent="351,50" Size="351,50" UserMovable="true" UserResizable="true">
<Button BackgroundOpacity="0.000" DynamicData="/GameData.Self.AutoAttack" DynamicDataFilter="0001" Name="MeleeTrigger" OnHide="Parent.MeleeAutoAttack.Primary.Progress.Bar.Color=&apos;#C7CFC7&apos;&#xD;&#xA;Parent.MeleeAutoAttack.Secondary.Progress.Bar.Color=&apos;#C7CFC7&apos;" OnShow="Parent.MeleeAutoAttack.Primary.Progress.Bar.Color=&apos;#FF0000&apos;&#xD;&#xA;Parent.MeleeAutoAttack.Secondary.Progress.Bar.Color=&apos;#00FFFF&apos;" />
<Button BackgroundOpacity="0.000" DynamicData="/GameData.Self.RangedAutoAttack" DynamicDataFilter="0001" Name="RangedTrigger" OnHide="Parent.RangedAutoAttack.Ranged.Bar.Color=&apos;#C7CFC7&apos;" OnShow="Parent.RangedAutoAttack.Ranged.Bar.Color=&apos;#FF0000&apos;" />
<Button BackgroundOpacity="0.000" COND="true" Name="DelayTrigger" OnPress="COND=(Parent.PrimaryDelay.Text == Parent.SecondaryDelay.Text)&#xD;&#xA;COND=COND ? false : true&#xD;&#xA;Parent.MeleeAutoAttack.Secondary.Visible=COND" />
<Text COND="true" DynamicData="/GameData.Stats.Primary_Delay" Name="PrimaryDelay" OnTextChanged="COND=(Text == &apos;&apos;)&#xD;&#xA;COND=COND ? false : true&#xD;&#xA;Parent.MeleeAutoAttack.Primary.Visible=COND&#xD;&#xA;Parent.DelayTrigger.Press=true" TextAlignment="Right" TextAlignmentVertical="Center">100</Text>
<Text DynamicData="/GameData.Stats.Secondary_Delay" Name="SecondaryDelay" OnTextChanged="Parent.DelayTrigger.Press=true" TextAlignment="Right" TextAlignmentVertical="Center">50</Text>
<Composite Location="1,1" Name="MeleeAutoAttack" OnHide="Parent.Visible=Parent.RangedAutoAttack.Visible" OnShow="Parent.RangedAutoAttack.Visible=false&#xD;&#xA;Parent.Visible=true&#xD;&#xA;show_window Custom.AutoAttackTimer" PackSize="a,f" ScrollExtent="349,48" Size="349,48" SpacingType="Fill">
<Text AbsorbsInput="false" Font="/TextStyles.Large.LargeStyle" MaximumSize="16384,21" Name="Text" PackSize="a,f" ScrollExtent="349,21" ShadowStyle="/ShadowStylesNew.OutlineDrop.style" Size="349,21" TextAlignment="Center" TextColor="#F0D080">Melee Auto Attack</Text>
<Page Location="0,21" MaximumSize="16384,13" Name="Primary" PackSize="a,f" ScrollExtent="349,13" Size="349,13">
<Page DynamicData="/GameData.Self.TimeSinceAutoAttack" DynamicDataFilter="0001" Name="Progress" OnHide="Parent.Parent.Visible=Parent.Parent.Secondary.Progress.Visible&#xD;&#xA;Parent.Visible=false" OnShow="Parent.Visible=Parent.Parent.Parent.PrimaryDelay.COND&#xD;&#xA;Parent.Parent.Visible=true" PackSize="a,f" ScrollExtent="349,14" Size="349,14">
<Page AbsorbsInput="false" BackgroundOpacity="1.000" BackgroundTint="#000000" Enabled="false" GetsInput="false" Location="44,3" Name="125MarkerTop" Opacity="0.500" PackLocation="npn,nfn" PackSize="f,a" ScrollExtent="1,2" Size="1,2" />
<Page AbsorbsInput="false" BackgroundOpacity="1.000" BackgroundTint="#000000" Enabled="false" GetsInput="false" Location="44,9" Name="125MarkerBottom" Opacity="0.500" PackLocation="npn,nfn" PackSize="f,a" ScrollExtent="1,2" Size="1,2" />
<Page AbsorbsInput="false" BackgroundOpacity="1.000" BackgroundTint="#000000" Enabled="false" GetsInput="false" Location="87,3" Name="25Marker" Opacity="0.500" PackLocation="npn,nfn" PackSize="f,a" ScrollExtent="1,8" Size="1,8" />
<Page AbsorbsInput="false" BackgroundOpacity="1.000" BackgroundTint="#000000" Enabled="false" GetsInput="false" Location="130,3" Name="375MarkerTop" Opacity="0.500" PackLocation="npn,nfn" PackSize="f,a" ScrollExtent="1,2" Size="1,2" />
<Page AbsorbsInput="false" BackgroundOpacity="1.000" BackgroundTint="#000000" Enabled="false" GetsInput="false" Location="130,9" Name="375MarkerBottom" Opacity="0.500" PackLocation="npn,nfn" PackSize="f,a" ScrollExtent="1,2" Size="1,2" />
<Page AbsorbsInput="false" BackgroundOpacity="1.000" BackgroundTint="#000000" Enabled="false" GetsInput="false" Location="174,3" Name="50Marker" Opacity="0.500" PackLocation="npn,nfn" PackSize="f,a" ScrollExtent="1,8" Size="1,8" />
<Page AbsorbsInput="false" BackgroundOpacity="1.000" BackgroundTint="#000000" Enabled="false" GetsInput="false" Location="217,3" Name="625MarkerTop" Opacity="0.500" PackLocation="npn,nfn" PackSize="f,a" ScrollExtent="1,2" Size="1,2" />
<Page AbsorbsInput="false" BackgroundOpacity="1.000" BackgroundTint="#000000" Enabled="false" GetsInput="false" Location="217,9" Name="625MarkerBottom" Opacity="0.500" PackLocation="npn,nfn" PackSize="f,a" ScrollExtent="1,2" Size="1,2" />
<Page AbsorbsInput="false" BackgroundOpacity="1.000" BackgroundTint="#000000" Enabled="false" GetsInput="false" Location="260,3" Name="75Marker" Opacity="0.500" PackLocation="npn,nfn" PackSize="f,a" ScrollExtent="1,8" Size="1,8" />
<Page AbsorbsInput="false" BackgroundOpacity="1.000" BackgroundTint="#000000" Enabled="false" GetsInput="false" Location="304,3" Name="875MarkerTop" Opacity="0.500" PackLocation="npn,nfn" PackSize="f,a" ScrollExtent="1,2" Size="1,2" />
<Page AbsorbsInput="false" BackgroundOpacity="1.000" BackgroundTint="#000000" Enabled="false" GetsInput="false" Location="304,9" Name="875MarkerBottom" Opacity="0.500" PackLocation="npn,nfn" PackSize="f,a" ScrollExtent="1,2" Size="1,2" />
<Progressbar AbsorbsInput="false" BackgroundColor="#000000" Color="#FF0000" DynamicData="/GameData.Self.TimeSinceAutoAttack" Location="3,3" Name="Bar" PackSize="a,a" Progress="0.500" ScrollExtent="343,8" Size="343,8" Style="progress_style" />
<Image AbsorbsInput="false" Location="3,3" Name="Bkg" PackSize="a,a" ScrollExtent="343,8" Size="343,8" SourceRect="338,472,339,478" SourceResource="images/window_elements_generic.dds" />
<Page AbsorbsInput="false" BackgroundOpacity="1.000" Name="Frame" PackSize="a,a" RStyleDefault="/rectlist.chat_bubble_frame" ScrollExtent="349,14" Size="349,14" />
</Page>
</Page>
<Page Location="0,34" MaximumSize="16384,14" Name="Secondary" PackSize="a,f" ScrollExtent="349,14" Size="349,14">
<Page DynamicData="/GameData.Self.TimeSinceSecondaryAutoAttack" DynamicDataFilter="0001" Name="Progress" OnHide="Parent.Parent.Visible=Parent.Parent.Primary.Progress.Visible&#xD;&#xA;Parent.Parent.Primary.MaximumSize=&apos;16384,14&apos;&#xD;&#xA;Parent.Visible=false" OnShow="Parent.Visible=Parent.Parent.Parent.DelayTrigger.COND&#xD;&#xA;Parent.Parent.Primary.MaximumSize=&apos;16384,13&apos;&#xD;&#xA;Parent.Parent.Visible=true" PackSize="a,f" ScrollExtent="349,14" Size="349,14">
<Page AbsorbsInput="false" BackgroundOpacity="1.000" BackgroundTint="#000000" Enabled="false" GetsInput="false" Location="44,3" Name="125MarkerTop" Opacity="0.500" PackLocation="npn,nfn" PackSize="f,a" ScrollExtent="1,2" Size="1,2" />
<Page AbsorbsInput="false" BackgroundOpacity="1.000" BackgroundTint="#000000" Enabled="false" GetsInput="false" Location="44,9" Name="125MarkerBottom" Opacity="0.500" PackLocation="npn,nfn" PackSize="f,a" ScrollExtent="1,2" Size="1,2" />
<Page AbsorbsInput="false" BackgroundOpacity="1.000" BackgroundTint="#000000" Enabled="false" GetsInput="false" Location="87,3" Name="25Marker" Opacity="0.500" PackLocation="npn,nfn" PackSize="f,a" ScrollExtent="1,8" Size="1,8" />
<Page AbsorbsInput="false" BackgroundOpacity="1.000" BackgroundTint="#000000" Enabled="false" GetsInput="false" Location="130,3" Name="375MarkerTop" Opacity="0.500" PackLocation="npn,nfn" PackSize="f,a" ScrollExtent="1,2" Size="1,2" />
<Page AbsorbsInput="false" BackgroundOpacity="1.000" BackgroundTint="#000000" Enabled="false" GetsInput="false" Location="130,9" Name="375MarkerBottom" Opacity="0.500" PackLocation="npn,nfn" PackSize="f,a" ScrollExtent="1,2" Size="1,2" />
<Page AbsorbsInput="false" BackgroundOpacity="1.000" BackgroundTint="#000000" Enabled="false" GetsInput="false" Location="174,3" Name="50Marker" Opacity="0.500" PackLocation="npn,nfn" PackSize="f,a" ScrollExtent="1,8" Size="1,8" />
<Page AbsorbsInput="false" BackgroundOpacity="1.000" BackgroundTint="#000000" Enabled="false" GetsInput="false" Location="217,3" Name="625MarkerTop" Opacity="0.500" PackLocation="npn,nfn" PackSize="f,a" ScrollExtent="1,2" Size="1,2" />
<Page AbsorbsInput="false" BackgroundOpacity="1.000" BackgroundTint="#000000" Enabled="false" GetsInput="false" Location="217,9" Name="625MarkerBottom" Opacity="0.500" PackLocation="npn,nfn" PackSize="f,a" ScrollExtent="1,2" Size="1,2" />
<Page AbsorbsInput="false" BackgroundOpacity="1.000" BackgroundTint="#000000" Enabled="false" GetsInput="false" Location="260,3" Name="75Marker" Opacity="0.500" PackLocation="npn,nfn" PackSize="f,a" ScrollExtent="1,8" Size="1,8" />
<Page AbsorbsInput="false" BackgroundOpacity="1.000" BackgroundTint="#000000" Enabled="false" GetsInput="false" Location="304,3" Name="875MarkerTop" Opacity="0.500" PackLocation="npn,nfn" PackSize="f,a" ScrollExtent="1,2" Size="1,2" />
<Page AbsorbsInput="false" BackgroundOpacity="1.000" BackgroundTint="#000000" Enabled="false" GetsInput="false" Location="304,9" Name="875MarkerBottom" Opacity="0.500" PackLocation="npn,nfn" PackSize="f,a" ScrollExtent="1,2" Size="1,2" />
<Progressbar AbsorbsInput="false" BackgroundColor="#000000" Color="#00FFFF" DynamicData="/GameData.Self.TimeSinceSecondaryAutoAttack" Location="3,3" Name="Bar" PackSize="a,a" Progress="0.500" ScrollExtent="343,8" Size="343,8" Style="progress_style" />
<Image AbsorbsInput="false" Location="3,3" Name="Bkg" PackSize="a,a" ScrollExtent="343,8" Size="343,8" SourceRect="338,472,339,478" SourceResource="images/window_elements_generic.dds" />
<Page AbsorbsInput="false" BackgroundOpacity="1.000" Name="Frame" PackSize="a,a" RStyleDefault="/rectlist.chat_bubble_frame" ScrollExtent="349,14" Size="349,14" />
</Page>
</Page>
</Composite>
<Page DynamicData="/GameData.Self.TimeSinceRangedAutoAttack" DynamicDataFilter="0001" Location="1,1" Name="RangedAutoAttack" OnHide="Parent.Visible=Parent.MeleeAutoAttack.Visible" OnShow="Parent.MeleeAutoAttack.Visible=false&#xD;&#xA;Parent.Visible=true&#xD;&#xA;show_window Custom.AutoAttackTimer" PackSize="a,f" ScrollExtent="349,49" Size="349,49">
<Text AbsorbsInput="false" Font="/TextStyles.Large.LargeStyle" MaximumSize="16384,21" Name="Text" PackSize="a,f" ScrollExtent="349,21" ShadowStyle="/ShadowStylesNew.OutlineDrop.style" Size="349,21" TextAlignment="Center" TextColor="#F0D080">Ranged Auto Attack</Text>
<Page Location="0,21" MaximumSize="16384,14" Name="Ranged" PackSize="a,f" ScrollExtent="349,14" Size="349,14">
<Page AbsorbsInput="false" BackgroundOpacity="1.000" BackgroundTint="#000000" Enabled="false" GetsInput="false" Location="44,3" Name="125MarkerTop" Opacity="0.500" PackLocation="npn,nfn" PackSize="f,a" ScrollExtent="1,2" Size="1,2" />
<Page AbsorbsInput="false" BackgroundOpacity="1.000" BackgroundTint="#000000" Enabled="false" GetsInput="false" Location="44,9" Name="125MarkerBottom" Opacity="0.500" PackLocation="npn,nfn" PackSize="f,a" ScrollExtent="1,2" Size="1,2" />
<Page AbsorbsInput="false" BackgroundOpacity="1.000" BackgroundTint="#000000" Enabled="false" GetsInput="false" Location="87,3" Name="25Marker" Opacity="0.500" PackLocation="npn,nfn" PackSize="f,a" ScrollExtent="1,8" Size="1,8" />
<Page AbsorbsInput="false" BackgroundOpacity="1.000" BackgroundTint="#000000" Enabled="false" GetsInput="false" Location="130,3" Name="375MarkerTop" Opacity="0.500" PackLocation="npn,nfn" PackSize="f,a" ScrollExtent="1,2" Size="1,2" />
<Page AbsorbsInput="false" BackgroundOpacity="1.000" BackgroundTint="#000000" Enabled="false" GetsInput="false" Location="130,9" Name="375MarkerBottom" Opacity="0.500" PackLocation="npn,nfn" PackSize="f,a" ScrollExtent="1,2" Size="1,2" />
<Page AbsorbsInput="false" BackgroundOpacity="1.000" BackgroundTint="#000000" Enabled="false" GetsInput="false" Location="174,3" Name="50Marker" Opacity="0.500" PackLocation="npn,nfn" PackSize="f,a" ScrollExtent="1,8" Size="1,8" />
<Page AbsorbsInput="false" BackgroundOpacity="1.000" BackgroundTint="#000000" Enabled="false" GetsInput="false" Location="217,3" Name="625MarkerTop" Opacity="0.500" PackLocation="npn,nfn" PackSize="f,a" ScrollExtent="1,2" Size="1,2" />
<Page AbsorbsInput="false" BackgroundOpacity="1.000" BackgroundTint="#000000" Enabled="false" GetsInput="false" Location="217,9" Name="625MarkerBottom" Opacity="0.500" PackLocation="npn,nfn" PackSize="f,a" ScrollExtent="1,2" Size="1,2" />
<Page AbsorbsInput="false" BackgroundOpacity="1.000" BackgroundTint="#000000" Enabled="false" GetsInput="false" Location="260,3" Name="75Marker" Opacity="0.500" PackLocation="npn,nfn" PackSize="f,a" ScrollExtent="1,8" Size="1,8" />
<Page AbsorbsInput="false" BackgroundOpacity="1.000" BackgroundTint="#000000" Enabled="false" GetsInput="false" Location="304,3" Name="875MarkerTop" Opacity="0.500" PackLocation="npn,nfn" PackSize="f,a" ScrollExtent="1,2" Size="1,2" />
<Page AbsorbsInput="false" BackgroundOpacity="1.000" BackgroundTint="#000000" Enabled="false" GetsInput="false" Location="304,9" Name="875MarkerBottom" Opacity="0.500" PackLocation="npn,nfn" PackSize="f,a" ScrollExtent="1,2" Size="1,2" />
<Progressbar AbsorbsInput="false" BackgroundColor="#000000" Color="#FF0000" DynamicData="/GameData.Self.TimeSinceRangedAutoAttack" Location="3,3" Name="Bar" PackSize="a,a" Progress="0.500" ScrollExtent="343,8" Size="343,8" Style="progress_style" />
<Image AbsorbsInput="false" Location="3,3" Name="Bkg" PackSize="a,a" ScrollExtent="343,8" Size="343,8" SourceRect="338,472,339,478" SourceResource="images/window_elements_generic.dds" />
<Page AbsorbsInput="false" BackgroundOpacity="1.000" Name="Frame" PackSize="a,a" RStyleDefault="/rectlist.chat_bubble_frame" ScrollExtent="349,14" Size="349,14" />
</Page>
</Page>
<ProgressbarStyle Bar.Background="progress_fill" Name="progress_style" />
<ImageStyle Name="progress_fill">
<ImageFrame Name="progress_fill" Source="images/window_elements_specific.dds" SourceRect="441,342,442,355" />
</ImageStyle>
</Page>


speedycerv 08-09-2009 01:49 PM

I played around with some ACT settings for beeps when auto attack goes off. It seemed semi-fixed after this. I think the problem might be server lag or something is wrong with my system that is affecting this and might not be Windows 7. My computer has been crashing every other day or so, and thus things may be wonky.

samejima 08-09-2009 02:15 PM

Since this is bumped let me ask! I loaded yours, mine and the test window I have made, I saw absolutely zero difference between them. So what was buggy about mine that yours fixed?

dragowulf 08-09-2009 03:43 PM

Well I was using an older version with your Razc ui before I made mine and there were a few things I didn't like. I'll try to check out your newest standalone version vs. mine.

I'm not here to compete. I tend to like to mod windows catered to my own needs.

dragowulf 08-09-2009 04:50 PM

Quote:

Originally Posted by samejima (Post 85140)
Since this is bumped let me ask! I loaded yours, mine and the test window I have made, I saw absolutely zero difference between them. So what was buggy about mine that yours fixed?

After loading both of our updated and most recent code, I established within five minutes of testing that there are several factors that distinguish our mods from one another. Within the mentioned testing time, I saw no bugs in either of our mods.

Important differences/similarities:

Both of our mod's "core features":
- Functions as auto attack timers
- Horizontal resizeability
- Vertical resizeability that allows the user to hide the Secondary bar if so chosen
- Lock/Click through works flawlessly

Your mod "feature list":
- Toggles when you're hated
- Bars turn a different color when you're hated and not auto attacking
- If the frame is on, the Secondary bar does not remain visible when the Primary/Secondary delays are both the same

My mod "feature list":
- Toggles when auto attack is enabled/disabled
- Bars become tinted when auto attack is changed/disabled during an auto attack
- Secondary bar does not remain visible when the Primary/Secondary delays are both the same
- Bars turn red while you're casting
- 10%, 20%, 30%, 40%, 50%, 60%, 70%, 80%, 90% visual indicators, which I will probably remove because their usefulness is minimal
- No "dead space"


Now to answer your question: I thought the "Toggles when you're hated" was some bug, obviously it was intentional.
Now to reply to your statement: Like I said in my previous most, I tend to like to mod windows catered to my own needs. The things that I listed on both your mod and my mod is what distinguishes our mods from one another. Everything I listed on both of our mod's "core features" is what you and me both implemented in our mods, which I like. Everything I listed on your mod is pretty much your "feature list", which I dislike. Everything I listed on my mod is pretty much my "feature list", which I like.

IMO, everything that has been mentioned above is enough to warrant two separate mods.

samejima 08-09-2009 05:52 PM

Quote:

Originally Posted by dragowulf (Post 85145)
Well I was using an older version with your Razc ui before I made mine and there were a few things I didn't like. I'll try to check out your newest standalone version vs. mine.

I'm not here to compete. I tend to like to mod windows catered to my own needs.

In no way did I take it that way bud, I was just curious about what bugs you had found.

dragowulf 08-09-2009 07:26 PM

Quote:

Originally Posted by samejima (Post 85149)
In no way did I take it that way bud, I was just curious about what bugs you had found.

As I mentioned in my previous post, I thought that the toggle when hated was a bug because with my Coercer I never had auto attack enabled when I was in combat, but the bars were up. I figured that was a bug.


All times are GMT -5. The time now is 08:11 PM.

vBulletin® - Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
© MMOUI