cancel
Showing results for 
Search instead for 
Did you mean: 
Reply
Alastair
Advocate II
Advocate II

Improving the efficiency of this ForAll Formula

Hello Everyone

 

I have created a ForAll formula that finds processes related to each Property that the user has selected.  This formula works as intended however I feel is not as efficient as it could be.  This is because for each selected Property it has to refilter the entire Property Processes list, i.e. search through the whole list again for a single value.  The commented formula I am currently using is below.

PropertyProcessFormula.PNG

 

This is a bit of an open-ended question as I'm interested in any and all ways to improve the efficiency of the formula.  One thing that I think would improve the efficiency but Im not sure how to implement, is to Filter on all selected Property values at the same time instead of doing it one at a time. (I.e. checks whether each Process in the SP list is related to any of the selected Properties).

 

For clarity, what I mean by efficiency is how long the formula takes to finish running

9 REPLIES 9
Pstork1
Most Valuable Professional
Most Valuable Professional

The real problem here is that Power Apps is a declarative application rather than a procedural one.  The ForAll() function isn't an actual loop and is therefore quite inefficient.  The best way to improve that efficiency is to pass the task off to a procedural application.  That's where Power Automate comes in.  As a workflow engine this is the kind of work that Power Automate is designed to do.  You can easily pass the collection to a flow as a JSON array, process it in Power Apps, and then return the results and store them as a collection.



-------------------------------------------------------------------------
If I have answered your question, please mark your post as Solved.
If you like my response, please give it a Thumbs Up.
Alastair
Advocate II
Advocate II

Thanks for the answer.  Power Automate does make sense as a better solution.   Are there any potential hiccups with using Power Automate?  I'm slightly cautious in using it for this scenario, as I'm expecting the function will be called frequently by simultaneous users.  

RandyHayes
Super User
Super User

@Alastair 

As @Pstork1 mentions, you will not get a lot of gain in performance with the ForAll for large operations.

Once slight advantage is to actually use the ForAll as it is intended rather than a For/Loop in development as it is not.

 

So, the ForAll produces a Table...you should use it.

ClearCollect(varPropertyProcess,
    ForAll(varProperties,
        Filter('Property Processes',
            Property.Value = SelectedProperty.Title &&
            (IsBlank(SelectedYear) || SelectedYear = Year)
        )
    )
)

 

A couple of things though:

1) Your collection is going to be a table with a single column called Value that will have a table of duplicated items based on the Filter for the iterations of the varProperties collection.

 

2) You will increase your performance in your app by not using collections as they must gather all their data in these type of formulas.  You would be better off working directly with the datasource object rather than duplicating what is already a duplicate of the duplicated cloud session table that is a duplicate of the real data source (get the idea of how much duplication goes on?)

 

2) Your Year statement in the Filter appears to have an incompatible type.  I am not sure where and what SelectedYear or Year are in your formula, so I can not add any advice to that.

 

You would be better off, as mentioned, working with the datasource directly and to include this filter as part of that process.

 

The farther you stay away from behavioral actions like you have, the better your performance will be and the less work you will have to do.

 

I hope this is helpful for you.

 

_____________________________________________________________________________________
Digging it? - Click on the Thumbs Up below. Solved your problem? - Click on Accept as Solution below. Others seeking the same answers will be happy you did.
NOTE: My normal response times will be Mon to Fri from 1 PM to 10 PM UTC (and lots of other times too!)
Check out my PowerApps Videos too! And, follow me on Twitter @RandyHayes

Really want to show your appreciation? Buy Me A Cup Of Coffee!

Thanks for your response.  

 

For the Year its comparing string to int is why its blue.  Easy enough to resolve once the rest of it comes together.  

 

Im very much interested in avoiding the use of collections where possible to improve performance, however this is how I've always done it, so I would appreciate a bit of guidance on where to start. 

 

For the  varPropertyProcesses collection I use the collection to both display each process returned in a gallery and to generate a pie chart of there statuses. The collection is there so I only have to filter down to the records I care about once and then send the result to both. Is it better to filter twice and run directly off the SP datasource or is there an even better way to go about it? 

RandyHayes
Super User
Super User

@Alastair 

Ah, you need one of my favorite "dynamic variables".  

 

Let's take a short explanative journey first to explain what that means - grab some popcorn!

 

Collections:

A collection is way overused (and unfortunately what everyone demonstrates their formulas with).  A collection is an in-memory database.  It is a Table.  It has the ability to add or remove rows to the table.  That is all it brings to the party.  Collections must be filled with information.  This results in a duplicate of the original information. Collections are "glorified" variables in that they have the add/remove ability, but, just like variables, they are a Snapshot of data at the time they are collected.  They do not change unless you change them (which is just more overhead for your app).

Collections are good for two things - when you are designing an offline capable app, or you NEED the ability to easily add or remove rows.

 

Variables:

A variable can be anything - text, number, boolean, Table, record, etc.

We can leverage the Table aspect of this by using a variable rather than a collection when we don't need the add/remove rows ability - this reduces overhead on the app.   

Variables are snapshots of information at the time they are assigned.  They do not change unless you change them.

 

PowerApps

PowerApps is built around the concept of Excel.  You use formulas in Excel to calculate values. Once you have values in cells (either by formula or by hand) you then reference those cells to build additional calculations or results in other cells.  You do NOT set variables to the cell value so that you can then reference the variable value in other cells...that would be too complex - and so too it is in PowerApps.

In PowerApps, you reference results as much as possible. 

Until now, the above (collections and variables) are very programmatic in nature.  PowerApps is a no-code design platform, not a development platform.

 

So..."Dynamic Variables"

The concept is simple following the Excel concept.  If you set a Label, for example, to something like a LookUp column result, then you can reference that Label text property from anywhere in your app.  Plus, if it is based on a datasource, then it will simply change as the datasource changes (the dynamic part).  So, if I set the text property of the label to : LookUp(datasource, ID=1, Title) then the label will show the Title value for the record with the ID of 1.  If, in the app, I change the Title with a form, or a patch or update or anything else, then that label value will change automatically (just like changing a value in your Excel cell will change the cells that have formulas based off of it).   

This concept can be used all over your app to first, reduce the amount of duplication of your formulas, but also to reduce the amount of work you have to do to maintain that value.  It is all dynamic.

 

Dynamic Table Variables

So, the above is great for simple values like text and number and boolean is great, but (as in your case) you want to have a table of records for a Gallery and the same Table of records for a chart.  How to do that??

Well, there is a little know process for doing this in PowerApps.  It comes from a Datacard.  Not a form datacard, but a Canvas datacard.  If you add a scrollable screen to your app, you will get a Canvas control.  In that Canvas control will be a Datacard.  You can cut and paste the entire canvas control from that screen (and get rid of the screen if you want) in order to paste it into a place that you would like in the app.  The Canvas will be invisible (Visible : false).  It can be sized small and out of your way as well.  There is ONLY one thing you want in that - the datacard.

Reason being, the DataCard has a property called Update - it is a Record property.  The Update property can be anything you want.  And, in this case, we're going to make it a table (actually a record with a table).

So, in the Update property a formula such as this:  LookUp(datasource, ID=1)  The datacard will now have an Update property that is the FULL record of the lookup.  You can reference this from anywhere : datacardname.Update.Title will produce the Title column value for the record.  If the record is changed in your app...so too will the Update property automatically change.

Now...the Table (because that is what you want for a Gallery and a chart).

If we set our Update property to something like this:  {Items: Filter(datasource, criteria)}

We will now have a dynamically changing "variable" in the app.  You can reference the table from the Items property of the Gallery as such :  datacardname.Update.Items and the same for the chart.

You could even shape that update property even more with things like:

{Items: Filter(dataSource, criteria), chartData: Filter(..etc..)}

Now we have two columns in the Update property record that can be referenced and will be dynamic based on changes in the app.

 

This completely eliminates the need to have behavioral actions to build collections and variables just because you know that the data has changed.  Very often see people doing a Patch on a record and then recollecting their entire collection again from the datasource to "keep the app up-to-date".  With the "dynamic variable" there is no need...the Update property will already have its new data and you can just reference that as needed.

 

Anyway, that is the basics of it.  One day I will get the opportunity to complete the video I have on this concept, but for now, the above pretty much describes it.

 

I hope it is clear and helpful for you - it just might change everything for you in how you design your apps!

 

 

 

_____________________________________________________________________________________
Digging it? - Click on the Thumbs Up below. Solved your problem? - Click on Accept as Solution below. Others seeking the same answers will be happy you did.
NOTE: My normal response times will be Mon to Fri from 1 PM to 10 PM UTC (and lots of other times too!)
Check out my PowerApps Videos too! And, follow me on Twitter @RandyHayes

Really want to show your appreciation? Buy Me A Cup Of Coffee!
Alastair
Advocate II
Advocate II

The Dynamic variables sound really good.  Just a shame that Microsoft decides to hide really powerful functionality so you have to jump a few hoops to get the component you want.  Will take a crack at getting a proof of concept working for both Dynamic variables and Dynamic Table variables so I can understand how they work fully.   

 

I do have two questions about Dynamic variables though.  

  1. Are there any issues with Dynamic variables (& table variables) when used within large lists.  One of my lists is around the 90,000 record mark.  
  2. Are they just as useful when used in conjunction with the Dataverse? Are they still needed? With the above we're looking to move to Dataverse in the near future.  
  3. Is there a place where I can find your videos?  
RandyHayes
Super User
Super User

@Alastair 

Yes, they are powerful.  I believe that Microsoft and others stick with the bare essentials when describing what to do.  It's reminiscent of when listening to a presenter present a function in a technology and preface it with "Now you wouldn't really do this, but I am doing it to demonstrate quickly."

 

Your questions:

1) The dynamic variables are as limited as much as your record limit in your app and the ability to delegate your criteria.  If you can delegate criteria and you can have results to that criteria that are less than the record limit in your app, then you are just as fine with them as anything else.  If your actual results are over the record limit, then you will need to explore a more complicated approach (and also you'll need to ask yourself why you would want to return that many results to a user in a PowerApp).  

2) Yes, just as useful with any DataSource.  The DataVerse datasource is just like any other.

3) Yes, look at my signature line below...it has a link to my videos.

_____________________________________________________________________________________
Digging it? - Click on the Thumbs Up below. Solved your problem? - Click on Accept as Solution below. Others seeking the same answers will be happy you did.
NOTE: My normal response times will be Mon to Fri from 1 PM to 10 PM UTC (and lots of other times too!)
Check out my PowerApps Videos too! And, follow me on Twitter @RandyHayes

Really want to show your appreciation? Buy Me A Cup Of Coffee!

Hi @RandyHayes 

I am fascinated by your use of the datacard to hold a table and have now used it in my apps with great results.  Have  you made the video on this?  I would love to see it and any extensions of the concept. 

absolute game changer -- reduced process times by over 90% alongside another implementation i had that adds threading to ForAll. thank you for this!

Helpful resources

Announcements

Tuesday Tip: Community User Groups

t's time for another TUESDAY TIPS, your weekly connection with the most insightful tips and tricks that empower both newcomers and veterans in the Power Platform Community! Every Tuesday, we bring you a curated selection of the finest advice, distilled from the resources and tools in the Community. Whether you’re a seasoned member or just getting started, Tuesday Tips are the perfect compass guiding you across the dynamic landscape of the Power Platform Community.   As our community family expands each week, we revisit our essential tools, tips, and tricks to ensure you’re well-versed in the community’s pulse. Keep an eye on the News & Announcements for your weekly Tuesday Tips—you never know what you may learn!   Today's Tip: Community User Groups and YOU Being part of, starting, or leading a User Group can have many great benefits for our community members who want to learn, share, and connect with others who are interested in the Microsoft Power Platform and the low-code revolution.   When you are part of a User Group, you discover amazing connections, learn incredible things, and build your skills. Some User Groups work in the virtual space, but many meet in physical locations, meaning you have several options when it comes to building community with people who are learning and growing together!   Some of the benefits of our Community User Groups are: Network with like-minded peers and product experts, and get in front of potential employers and clients.Learn from industry experts and influencers and make your own solutions more successful.Access exclusive community space, resources, tools, and support from Microsoft.Collaborate on projects, share best practices, and empower each other. These are just a few of the reasons why our community members love their User Groups. Don't wait. Get involved with (or maybe even start) a User Group today--just follow the tips below to get started.For current or new User Group leaders, all the information you need is here: User Group Leader Get Started GuideOnce you've kicked off your User Group, find the resources you need:  Community User Group ExperienceHave questions about our Community User Groups? Let us know! We are here to help you!

Tuesday Tip: Getting Started with Private Messages & Macros

Welcome to TUESDAY TIPS, your weekly connection with the most insightful tips and tricks that empower both newcomers and veterans in the Power Platform Community! Every Tuesday, we bring you a curated selection of the finest advice, distilled from the resources and tools in the Community. Whether you’re a seasoned member or just getting started, Tuesday Tips are the perfect compass guiding you across the dynamic landscape of the Power Platform Community.   As our community family expands each week, we revisit our essential tools, tips, and tricks to ensure you’re well-versed in the community’s pulse. Keep an eye on the News & Announcements for your weekly Tuesday Tips—you never know what you may learn!   This Week's Tip: Private Messaging & Macros in Power Apps Community   Do you want to enhance your communication in the Community and streamline your interactions? One of the best ways to do this is to ensure you are using Private Messaging--and the ever-handy macros that are available to you as a Community member!   Our Knowledge Base article about private messaging and macros is the best place to find out more. Check it out today and discover some key tips and tricks when it comes to messages and macros:   Private Messaging: Learn how to enable private messages in your community profile and ensure you’re connected with other community membersMacros Explained: Discover the convenience of macros—prewritten text snippets that save time when posting in forums or sending private messagesCreating Macros: Follow simple steps to create your own macros for efficient communication within the Power Apps CommunityUsage Guide: Understand how to apply macros in posts and private messages, enhancing your interaction with the Community For detailed instructions and more information, visit the full page in your community today:Power Apps: Enabling Private Messaging & How to Use Macros (Power Apps)Power Automate: Enabling Private Messaging & How to Use Macros (Power Automate)  Copilot Studio: Enabling Private Messaging &How to Use Macros (Copilot Studio) Power Pages: Enabling Private Messaging & How to Use Macros (Power Pages)

April 4th Copilot Studio Coffee Chat | Recording Now Available

Did you miss the Copilot Studio Coffee Chat on April 4th? This exciting and informative session with Dewain Robinson and Gary Pretty is now available to watch in our Community Galleries!   This AMA discussed how Copilot Studio is using the conversational AI-powered technology to aid and assist in the building of chatbots. Dewain is a Principal Program Manager with Copilot Studio. Gary is a Principal Program Manager with Copilot Studio and Conversational AI. Both of them had great insights to share with the community and answered some very interesting questions!     As part of our ongoing Coffee Chat AMA series, this engaging session gives the Community the unique opportunity to learn more about the latest Power Platform Copilot plans, where we’ll focus, and gain insight into upcoming features. We’re looking forward to hearing from the community at the next AMA, so hang on to your questions!   Watch the recording in the Gallery today: April 4th Copilot Studio Coffee Chat AMA

Tuesday Tip: Subscriptions & Notifications

TUESDAY TIPS are our way of communicating helpful things we've learned or shared that have helped members of the Community. Whether you're just getting started or you're a seasoned pro, Tuesday Tips will help you know where to go, what to look for, and navigate your way through the ever-growing--and ever-changing--world of the Power Platform Community! We cover basics about the Community, provide a few "insider tips" to make your experience even better, and share best practices gleaned from our most active community members and Super Users.   With so many new Community members joining us each week, we'll also review a few of our "best practices" so you know just "how" the Community works, so make sure to watch the News & Announcements each week for the latest and greatest Tuesday Tips!   This Week: All About Subscriptions & Notifications We don't want you to a miss a thing in the Community! The best way to make sure you know what's going on in the News & Announcements, to blogs you follow, or forums and galleries you're interested in is to subscribe! These subscriptions ensure you receive automated messages about the most recent posts and replies. Even better, there are multiple ways you can subscribe to content and boards in the community! (Please note: if you have created an AAD (Azure Active Directory) account you won't be able to receive e-mail notifications.)   Subscribing to a Category  When you're looking at the entire category, select from the Options drop down and choose Subscribe.     You can then choose to Subscribe to all of the boards or select only the boards you want to receive notifications. When you're satisfied with your choices, click Save.   Subscribing to a Topic You can also subscribe to a single topic by clicking Subscribe from the Options drop down menu, while you are viewing the topic or in the General board overview, respectively.     Subscribing to a Label Find the labels at the bottom left of a post.From a particular post with a label, click on the label to filter by that label. This opens a window containing a list of posts with the label you have selected. Click Subscribe.           Note: You can only subscribe to a label at the board level. If you subscribe to a label named 'Copilot' at board #1, it will not automatically subscribe you to an identically named label at board #2. You will have to subscribe twice, once at each board.   Bookmarks Just like you can subscribe to topics and categories, you can also bookmark topics and boards from the same menus! Simply go to the Topic Options drop down menu to bookmark a topic or the Options drop down to bookmark a board. The difference between subscribing and bookmarking is that subscriptions provide you with notifications, whereas bookmarks provide you a static way of easily accessing your favorite boards from the My subscriptions area.   Managing & Viewing Your Subscriptions & Bookmarks To manage your subscriptions, click on your avatar and select My subscriptions from the drop-down menu.     From the Subscriptions & Notifications tab, you can manage your subscriptions, including your e-mail subscription options, your bookmarks, your notification settings, and your email notification format.     You can see a list of all your subscriptions and bookmarks and choose which ones to delete, either individually or in bulk, by checking multiple boxes.     A Note on Following Friends on Mobile Adding someone as a friend or selecting Follow in the mobile view does not allow you to subscribe to their activity feed. You will merely be able to see your friends’ biography, other personal information, or online status, and send messages more quickly by choosing who to send the message to from a list, as opposed to having to search by username.

Monthly Community User Group Update | April 2024

The monthly Community User Group Update is your resource for discovering User Group meetings and events happening around the world (and virtually), welcoming new User Groups to our Community, and more! Our amazing Community User Groups are an important part of the Power Platform Community, with more than 700 Community User Groups worldwide, we know they're a great way to engage personally, while giving our members a place to learn and grow together.   This month, we welcome 3 new User Groups in India, Wales, and Germany, and feature 8 User Group Events across Power Platform and Dynamics 365. Find out more below. New Power Platform User Groups   Power Platform Innovators (India) About: Our aim is to foster a collaborative environment where we can share upcoming Power Platform events, best practices, and valuable content related to Power Platform. Whether you’re a seasoned expert or a newcomer looking to learn, this group is for you. Let’s empower each other to achieve more with Power Platform. Join us in shaping the future of digital transformation!   Power Platform User Group (Wales) About: A Power Platform User Group in Wales (predominantly based in Cardiff but will look to hold sessions around Wales) to establish a community to share learnings and experience in all parts of the platform.   Power Platform User Group (Hannover) About: This group is for anyone who works with the services of Microsoft Power Platform or wants to learn more about it and no-code/low-code. And, of course, Microsoft Copilot application in the Power Platform.   New Dynamics365 User Groups   Ellucian CRM Recruit UK (United Kingdom) About: A group for United Kingdom universities using Ellucian CRM Recruit to manage their admissions process, to share good practice and resolve issues.    Business Central Mexico (Mexico City) About:  A place to find documentation, learning resources, and events focused on user needs in Mexico. We meet to discuss and answer questions about the current features in the standard localization that Microsoft provides, and what you only find in third-party locations. In addition, we focus on what's planned for new standard versions, recent legislation requirements, and more. Let's work together to drive request votes for Microsoft for features that aren't currently found—but are indispensable.   Dynamics 365 F&O User Group (Dublin) About: The Dynamics 365 F&O User Group - Ireland Chapter meets up in person at least twice yearly in One Microsoft Place Dublin for users to have the opportunity to have conversations on mutual topics, find out what’s new and on the Dynamics 365 FinOps Product Roadmap, get insights from customer and partner experiences, and access to Microsoft subject matter expertise.  Upcoming Power Platform Events    PAK Time (Power Apps Kwentuhan) 2024 #6 (Phillipines, Online) This is a continuation session of Custom API. Sir Jun Miano will be sharing firsthand experience on setting up custom API and best practices. (April 6, 2024)       Power Apps: Creating business applications rapidly (Sydney) At this event, learn how to choose the right app on Power Platform, creating a business application in an hour, and tips for using Copilot AI. While we recommend attending all 6 events in the series, each session is independent of one another, and you can join the topics of your interest. Think of it as a “Hop On, Hop Off” bus! Participation is free, but you need a personal computer (laptop) and we provide the rest. We look forward to seeing you there! (April 11, 2024)     April 2024 Cleveland Power Platform User Group (Independence, Ohio) Kickoff the meeting with networking, and then our speaker will share how to create responsive and intuitive Canvas Apps using features like Variables, Search and Filtering. And how PowerFx rich functions and expressions makes configuring those functionalities easier. Bring ideas to discuss and engage with other community members! (April 16, 2024)     Dynamics 365 and Power Platform 2024 Wave 1 Release (NYC, Online) This session features Aric Levin, Microsoft Business Applications MVP and Technical Architect at Avanade and Mihir Shah, Global CoC Leader of Microsoft Managed Services at IBM. We will cover some of the new features and enhancements related to the Power Platform, Dataverse, Maker Portal, Unified Interface and the Microsoft First Party Apps (Microsoft Dynamics 365) that were announced in the Microsoft Dynamics 365 and Power Platform 2024 Release Wave 1 Plan. (April 17, 2024)     Let’s Explore Copilot Studio Series: Bot Skills to Extend Your Copilots (Makati National Capital Reg... Join us for the second installment of our Let's Explore Copilot Studio Series, focusing on Bot Skills. Learn how to enhance your copilot's abilities to automate tasks within specific topics, from booking appointments to sending emails and managing tasks. Discover the power of Skills in expanding conversational capabilities. (April 30, 2024)   Upcoming Dynamics365 Events    Leveraging Customer Managed Keys (CMK) in Dynamics 365 (Noida, Uttar Pradesh, Online) This month's featured topic: Leveraging Customer Managed Keys (CMK) in Dynamics 365, with special guest Nitin Jain from Microsoft. We are excited and thankful to him for doing this session. Join us for this online session, which should be helpful to all Dynamics 365 developers, Technical Architects and Enterprise architects who are implementing Dynamics 365 and want to have more control on the security of their data over Microsoft Managed Keys. (April 11, 2024)     Stockholm D365 User Group April Meeting (Stockholm) This is a Swedish user group for D365 Finance and Operations, AX2012, CRM, CE, Project Operations, and Power BI.  (April 17, 2024)         Transportation Management in D365 F&SCM Q&A Session (Toronto, Online) Calling all Toronto UG members and beyond! Join us for an engaging and informative one-hour Q&A session, exclusively focused on Transportation Management System (TMS) within Dynamics 365 F&SCM. Whether you’re a seasoned professional or just curious about TMS, this event is for you. Bring your questions! (April 26, 2024)   Leaders, Create Your Events!    Leaders of existing User Groups, don’t forget to create your events within the Community platform. By doing so, you’ll enable us to share them in future posts and newsletters. Let’s spread the word and make these gatherings even more impactful! Stay tuned for more updates, inspiring stories, and collaborative opportunities from and for our Community User Groups.   P.S. Have an event or success story to share? Reach out to us – we’d love to feature you. Just leave a comment or send a PM here in the Community!

Exclusive LIVE Community Event: Power Apps Copilot Coffee Chat with Copilot Studio Product Team

We have closed kudos on this post at this time. Thank you to everyone who kudo'ed their RSVP--your invitations are coming soon!  Miss the window to RSVP? Don't worry--you can catch the recording of the meeting this week in the Community.  Details coming soon!   *****   It's time for the SECOND Power Apps Copilot Coffee Chat featuring the Copilot Studio product team, which will be held LIVE on April 3, 2024 at 9:30 AM Pacific Daylight Time (PDT).     This is an incredible opportunity to connect with members of the Copilot Studio product team and ask them anything about Copilot Studio. We'll share our special guests with you shortly--but we want to encourage to mark your calendars now because you will not want to miss the conversation.   This live event will give you the unique opportunity to learn more about Copilot Studio plans, where we’ll focus, and get insight into upcoming features. We’re looking forward to hearing from the community, so bring your questions!   TO GET ACCESS TO THIS EXCLUSIVE AMA: Kudo this post to reserve your spot! Reserve your spot now by kudoing this post.  Reservations will be prioritized on when your kudo for the post comes through, so don't wait! Click that "kudo button" today.   Invitations will be sent on April 2nd.Users posting Kudos after April 2nd. at 9AM PDT may not receive an invitation but will be able to view the session online after conclusion of the event. Give your "kudo" today and mark your calendars for April 3rd, 2024 at 9:30 AM PDT and join us for an engaging and informative session!

Top Solution Authors
Top Kudoed Authors
Users online (5,398)