 talk of the day. Awesome. I wish I would have posted my slides earlier so I could show you how hilarious it's going to be as we go through. Most of the stuff that I'm going to talk about, like discoveries, have actually been talked about already. Jeremy actually put up three code examples that look almost identical to what I have on my slide. It's pretty awesome. So I might be on the right track. I don't know. Building reflow. I'm going to tell the story. I'm going to tell the story of creating this next generation app for Adobe from the beginnings to what we have today. And at the very end, I'm going to wrap it up with a demo of the application. Along the way, I'll show you things that we've learned, tips and tricks, and hopefully they'll be interesting. So who's this bozo? Adobe. How's that flash thing working out, right? Like what does Adobe know about HTML and the web? Isn't this a backbone conference? Yeah. So we have an entire team, a web platform team at Adobe that's dedicated to the web. And we've been working on a lot of things, adding to WebKit, created open source project brackets. Reflow is just one of these things that we've been working on. So what does this reflow you speak of? Well, let's start with a problem. So the problem that we had was I went and gave a talk on multi-stream design. And this is what you saw a lot was, you know, you had a website. You wanted to get it on these different screen sizes. And there really wasn't a way to see what the website was going to look like at design time. So what people were doing was this. You would get, you know, I would get, I was the developer on the design team. So they would give me four, five, six comps showing what the website looked like at different sizes. And I had to kind of sit back and imagine all these different steps, you know, what it would do when it resized, how things would flow. While not most of the time, I'll get pretty close. But there was really no way for me to know exactly what they were trying to accomplish. And yeah, there it is. This is what I'd be looking at all day. Just be a bunch of PSDs, multiple PSDs. So imagine someone goes, oh, yeah, we need to move the button up three pixels. So they go in and move the button up three pixels on all the different Photoshop files. And I go in and try and figure out what that meant to my actual final website. It was a really terrible workflow. So basically what we were trying to get to was we wanted to get, create a tool that could help designers express responsive intent. So they could show the developer or themselves even exactly what they wanted the website to do as it scaled from the different screens. So how did you do it? With Backbone, of course, how did we make a desktop application? The next generation of desktop application for Adobe, we did it with Backbone. It was weird. I had this conversation with the Edge anime team because they were much farther along than we were. And they said, well, what are you doing with them? Oh, HTML. Okay, so you're prototyping HTML? Yes, I'm prototyping HTML. Okay, cool. So what are you going to actually do it in? And you finally do the final thing. It's like, probably HTML. Okay, well, we'll see how that works out. It's like, okay. And so then I demoed the prototype. And the first question out of his mouth was, oh, how did you do it? Same story, same exact answer. And they said, okay, cool, because we tried it and he actually couldn't figure out how to get the performance in the feel right and whatnot. And I really give a lot of the credit to Backbone. And so the truth is, we iterated, we iterated a whole lot. We did, this prototype was a web page in a little shelf fluid. I think you guys have heard of it, this little fluid as an app wrapper that you can put websites in and it looks like a desktop app. And we did one week sprints. So we would talk about what we wanted to try to accomplish. We'd go and do customer validations. We'd research a bunch of websites. And then we'd go work on it for a week and then come back and whatever we had at the end of the week, we'd evaluate and decide we needed to pivot one way or the other. There was no way I could think of to get that fast of a turnaround with the features that we were putting in without doing it in web technology. I really couldn't come up with another way to do it. So the question that came up after that was, well, so you use Backbone, why would you use a framework at all? Aren't you supposed to be this JavaScript whiz kid? Can't you just write it all yourself? And the answer was, sure, I could write my own framework from the ground up. That's possible. Yeah, and I even started to try it. And I got done with models. I was like, oh, I need a model that when you set something on it, it emits an event. So I got that going. I was like, all right, cool, I got that. And I probably want to render this model in a template. So, okay, well, I got templates and then I got to, you know, where I'm going with this. I got the questions and I was like, all right, well, might as well just use Backbone. Which is good, because then we're actually living in the same space, we're feeling the same pain as other web developers. We actually understand the space a lot better, which I think is a really huge benefit for Adobe. But the final straw, the thing that won everyone over was onboarding, because every time you bring on a new person, they look at your code and they're like, what is going on? Because, you know, you did your best to document it. You did your best to explain it to them. And they're like, what are you doing? You're like, what the fuck is? So, it was way easier for us to point someone at the Backbone documentation and Stack Overflow. And not have to have that hour-long conversation about what idiots we were for not doing MVVM versus MVC versus whatever you want to do. I refer to this as the Pink Wheel Syndrome. I think a lot of people suffer from it. It's like, no, no, I'm not reinventing the wheel. I'm just making a pink one. It's like, well, sure, I guess that's fine. But it doesn't make it better just because you made it. It really doesn't. It actually makes it worse, because I feel something battle tested, something that's out in the community, something that people are actually pounding on. I heard this really great term for it. It's called used in anger. Something's been used in anger. It's going to be much better than something that you dreamed up. Prototype. Like you mean it. This, I think, was the huge determining factor. I wrote the prototype. I wrote the first lines of code on the prototype. And those first lines of code are still in the history of the final product, right? So, the only way that you're able to do that is if you prototype like you mean it, you actually write code like you were writing final, shipable, deliverable code, which means you write with tests. I had the accusation of writing the most over-architected prototype ever created. I was like, well, I'll take that. So, I wrote tests. I tested every single part of it. I was testing them from day one. I researched what I needed, and I was really pragmatic about it. I didn't just add a bunch of stuff, and kept making things until I felt incredible pain, and then we refactored, right? So, we actually treated like real code. We went all the way up to a point where we couldn't expand anymore, we couldn't scale, and then refactored that. So, we had a new level to base it off of. We started with, they talked about it, I think Brian talked about it, where we started out with that namespace module system, right? And it slowly evolved because we started seeing people cheating where they're, you know, taking an instance and then using the instance in the one-page app and then having circular dependencies. And then you actually had to load in the files. They're border-dependent. So, then we're like, oh, in their module system, you know, this is how it worked. We prototyped until we ran into problems like that that were actual real world problems, and then we changed things. So, this is an example of one of the prototypes that I made early on. And this is actually a little mini backbone app. Pay attention to these because I'm going to show the app at the end and it'll have the final output of this. So, these kind of prototypes, the interactive ones, I think they're really useful. Especially if you built it with the same technology stack because you can kind of, you can get, like, while we're trying to get the responsive intent across from the designer, I'm trying to get the actual functional intent, an interactive intent across to the final implement of the software. So, let's pop up one of them like this. I want to be able to, like, copy and paste these items. I wanted to see if it was even possible. I wanted to see if I could make a template that could render the items from this model in a way that was actually useful to the end user. Right? We're talking about, well, what's the best way to make to get it across to the user that how they can move things around on the screen, right? We're replicating things that we've done for years in tools like Illustrator and Photoshop in HTML. We wanted to know what the best way was. If it was even possible to do a lot of these things, right? Is there a way that we could get across the final intent in a way that wasn't annoying or confusing? And this is also a little backbone app just so I could try and figure out where the best way to go about it was for the final implementation. And then we actually got even deeper. Some of these are, like I said, we're reproducing things that we're used to in desktop applications in HTML. So, how do you do that when is it even possible? So this is our undo, redo, right? So I'm actually using design patterns that I know really well reproducing them in JavaScript and then trying to get it in a way that it's similar to familiar to people who use desktop apps or high quality desktop apps at Photoshop. So, first code example, yeah, it's exactly what Jeremy showed earlier, but you can see how backbone, because it's so flexible, lends itself to implementing these design patterns in a really JavaScript-y way, right? And then you get these really, really, really happy things like that where it's super easy to get the state of the attribute as it had changed. So, you prototype the things you don't think are possible. And in this case, they didn't think any of it was possible. So, we went through and prototyped as much as we possibly could and I think it was probably, I don't know, the single leading reason why it was successful. Modularity, a lessonary fact thing. So, like I said before, we have this single namespace modules. We also went down the path of trying to do our own AMD-like modules. And then, we decided at the end of the day to go with require. And I think it allowed us to scale in a way that we wouldn't be able to do it otherwise. I was kind of against it. I wanted to actually keep it more simple and require, setting it up like refactoring to use require was really, really, really painful. But doing it actually was super, super useful. We also came up with this idea. It actually looks a lot like what Brian was talking about where we have, we set up our modules in a way that basically you can work on a module individually. So, you get, if you looked at our project, you would have a folder of modules and they would be named after the different parts of the application. Properties panel, canvas, grid, right? And they all have this, what I call these, the entry point modules, the API. I think he was calling them controllers. But, basically what it does is you have all of your dependencies defined. This is our event map so that you can talk between the different modules. And then, all your backbone instances are brought in and instantiated by this controller. We have a save and load because what we're doing right now is we have the entire well, our canvas is all of the models rendered, visually, right? So, we basically when we instantiate the app, we hand off the models to the areas and they load, right? So, we have a load and save, we expose this API so that when the app starts up, we can go ahead and save, or we can load it up. And then, like I said, we subscribe to namespace events that come from other modules so that modules, we can develop the modules by themselves and they don't have any dependency on each other because we can put in modules and pull them out without making the app crash. Multiple inheritance. Angus crawl is a maze ball. Yeah, that's about it. No, multiple inheritance. So, a lot of the developers that came on the team were from, came from other languages, obviously, came from Java, came from ActionScript and they wanted to get this really elegant inheritance solution where they could make a base class and extend that base class and extend that base class and then all of a sudden we got to do a case where, well, you can add things to the canvas so we want to add view method on the canvas. Oh, but you can also add views to a box. And canvas and box aren't really related. They just both have this trait and so came up with the functional mixins just as a solution and I was like, I think this works really good. I think this is the way that I want to do all of our inheritance in the app. And I was like, really, that's how you want to do it? And then Angus Cole wrote this amazing article I have a link at the end of the slides about revisiting functional mixins and it's brilliant. I would go into a good detail about it but you should read the blog. This is amazing. Basically, this is it. You have a simple object with a bunch of functions on it and somewhere else when you want to use it, you just mix it in the prototype. Beautiful, beautiful, beautiful. Views, yeah. What should we use back on layout? Well, so when we started, there was a back on layout manager that didn't exist and we ended up going at views a bunch of different ways. The main issue that I ran into was that originally we had a lot of logic in our templates so you could hand it a really complicated model and go through and build all these views and it was really tedious to maintain and update. And then we started breaking down our render methods because we wanted to have faster renders to smaller and smaller and smaller views and smaller actions in the render methods so we had a bunch of render methods for the different parts of the view because you really find gain control, which is great. But then we wanted to have a way to basically say like, hey, properties panel go ahead and be created and create all of your panels inside of it and there was no way to specify that hierarchy with the way that we were doing it. We ended up having these really bloated views with these really bloated render methods even though we had them broken down it was still really hard to do. So if I were to do it again if I were to recommend what you should do something similar to back on layout manager I would use Mary Annette's one. So templates. We never needed more than underscore templates. It's weird. I talk to a lot of people that do back on projects and none of them use underscore template just straight up. And I don't really know why. I even had handlebars in the project fully intending to upgrade at some point to something more robust with all these fancy sugar syntax functions and whatnot. But I never needed it. And I'm actually pretty happy about that because when we did our final code review we said, oh, well, why do you have handlebars in there? I was like, oh, I'm actually not using them. We ripped it out. So the thing that got me the most though with templates was that we we had, like I said, before we had lots of logic in it and we got burned enough times by having a lot of logic in our template. So we just ripped most of the logic out. Right now all of our logic for the templates happens in preparing our models really well. And our templates are just reading things off of it. It's actually, if they render much faster there's way easier to debug and whatnot. Just like everything, I had to have some data behind my decisions for the architecture. And this is one of the things I stumbled upon that I thought was really interesting. I'm still waiting for someone to tell me that these benchmarks are BS. But this is dust JS, which is the most compelling as far as templating, because they have all this data behind how fast they are and what they can do and whatnot. But if you look, the trade-off of switching to something, like adding another dependency to your list of JavaScript is actually not that great, right? The trade-off isn't that good. So underscore actually does pretty well. If you look at handlebars, that's really good for just kind of the no off, the string. But then as you go down, like the things that I use all the time, like, underscore kind of hands handlebars its ass. So... Wait a minute. Show me how to do it. I'll update my suite and then we'll blow them away. What's that? So Jeremy says that he updated underscore so that you can render a template without the width and it's much faster, which is basically what dust is doing behind the scenes. Good to know. Okay. Collections. So there are a couple things that we ran into when we were doing our collections. One was mixed models. There wasn't really support for mixed models and we thought about it a lot, like, well, do we really need to have mixed models? Do we have a collection in it? Do we have multiple collections? We don't want to manage two collections. If you think about it, what I'm referring to is we have a canvas that has a bunch of things rendered on it. And those things are different. They're like text. There's also boxes. There's, you know, colors, gradients, whatnot. They're all items that can be drawn into the canvas, but there was no way to represent a box model as well as a text model and basically hand the data to the collection to all the views. So we came up with something interesting where we made this mixed models. We solved the mixed models problem by having a type on the model itself and then making this view factory and just mapping it. So it basically comes in, you hand a collection, all of these, you know, the big JSON object of all the models, and it goes through and it looks at the mapping. It's like, oh, well this type is a box. This type is text and it goes through and just creates the right view and it works pretty darn good. It's not the most elegant solution, but it works fine. And then this one, I'll show you a demo of it, the final output of this in the Typekit module of Reflow, but this is filterable collection. And again, it's proving that naming something in computer science is actually the hardest problem in coding. I couldn't come up with something better to call it but the thing I like about this is A, I love underscore for exposing more functional programming approaches. And B, it allowed us to do something, you know, it's kind of clunky, but it works really well and we don't have this issue of mutating our collection. We don't actually destroy or change any of the data. We actually just represent a different view on the data by using these filters on it and I can add and remove as many as I want and I get exactly what I need for the same collection. It's pretty fun. jQuery plugins. We have a bunch of jQuery plugins that we wrote for Reflow and it was interesting, I wasn't sure if it was the best way to go about it, but it ended up being actually quite nice because we could write a jQuery plugin that would work on any DOM and then we could put it into one, like wrap it in a backbone view and use it like it's just a DOM, a piece of DOM, and then we can do all the really complicated things that the great jQuery API makes easier inside this plugin and we could use it elsewhere if we wanted to, right? It's reusable. One of these is this cartilage grid. I'll show you it in the app, but this is the grid. The engine is a jQuery plugin so you basically just hand it some options and DOM element and it'll go ahead and create both the visualization and the grid itself in a scale away, right? Responsive grid. So I thought that was a pretty fun example of a jQuery plugin and then this is like, this is all pseudocode, don't expect this stuff to run, but this is basically what we're doing inside the backbone view and go ahead and set it up, run the cartilage function, which is just the plugin, the jQuery plugin and hand it the model which will have the options in it and then every time I call render, I'll go ahead and update the grid itself, just like it was the view. Testing. So I said this we, TDD from day one, we tested everything all the way through and I am going to be the dick that says this, you simply cannot make quality software without TDD. I just don't think you can. Have one guy on our team that can write perfect code every single time and I called him out on it and he proved me wrong multiple times, so for him I make an exception every now and then but everyone else, like you need to test your code and the main thing that the main takeaway I think for everyone about TDD is you can't refactor without tests. You can't do it and we did, we refactored every single week for 60 weeks so I wouldn't have been able to do that at all if I hadn't had tests for every single part of the application and again I'm repeating something that someone else said already today but side-on is awesome. This is I can't take credit for this at all Jared Wiles actually said you're an idiot we're not using side-on and I was like well I don't really want to have another dependency in our application. He's like trust me it's worth it. It's like I don't know so then he put this together and showed me man it's awesome because I showed you before we have that entry-level module which instantiates all the other parts of the module and there was no way to test it without basically testing other parts of the app we couldn't do a true unit test on those because we were testing that it could create these other objects as well stuffing these out and using sign-in for that makes it possible for us to have an actual unit test testing that part of it and then we because we use require we use squire as well and squire is basically just the injector so you can use dependency injection for your test and then someone asked about code coverage we're using sonar and it gives you these beautiful graphs of your code coverage it's pretty good I feel like code coverage for an app so I highly recommend using this it's great it gives you amazing statistics and it'll even give you hotspots where tests break often so you can go in and maybe see if there something you can change to make it less complex and so this is the app from prototype to production so you saw in the beginning it changed a lot and then as we started to solidify for demos it stopped moving so much add the grid the PI to the other side for some reason that's not going to customized our app wrapper so we did some design changes up top we couldn't decide whether we wanted to have default breakpoints or not and I say not I feel like you should design your website and then you should put a breakpoint where your web design breaks as you're resizing it you don't want to put in preset breakpoints because you might not need them you're doing extra work so that's that was after 60 weeks that's a snapshot every week for 60 weeks and then this is the final this is a reflow that's what it looks like today so now I'll demo okay so I can walk you through the different parts that I talk through in the slides first of all you notice there's this grid and you can see it's dynamic I can control the amount of columns whether it has our gutters or not the opacity of it if it's too much for you the gutters and then you can see as I resize it it'll scale I can even do cool things like I can go down here set a breakpoint change the grid maybe down here I only want three columns and then probably at the bottom I want just one once I get down to a single column and then it's faithful right you can see the different states the grid changes that's pretty cool you can put in elements and then this is the part that I was pretty excited about you don't really notice that it's HTML I mean the performance I was wondering if it was going to be too slow on the screen but you can see the performance is pretty darn good like it's snappy it feels native like you don't really even notice that we use anything other than cocoa for this and it has all the things that you'd expect it has a right click you can undo and redo it's like a real lap because it is a real lap this is that problem I was talking about I was able to add a box to the canvas and then I wanted to add something to the box in the canvas so that's where you have that view mix in so adding an item is actually accomplished by using that view mix in hello so this is that filterable collection in action so I can be like oh I want serif font someone says I want slab serifs I want that one and then this is the live filtering so I want source yeah source sounds pretty cool I got that one right so this is doing the live filtering on that filterable with that filterable filterable collection and I should name it something I could say right and then you can also go in and add your custom you can add your custom type information if you wanted to you see how it updates as I'm doing that this is kind of interesting you can do it default serams but you can set different types of units of a measurement that's actually a pretty fun thing to write as well switching the measurements on the fly so enough of me doing developer art oh wait maybe one more thing we have this experimental tab now this is where I'm going to be spending most of my life for the next year so is adding experimental web kit features so that we can basically vet them and get more support around them so this will have anything that Adobe works on will be in there anyway so then let's load a project so you see here I have this website that has all these different sizes to fit these different screens D 1024 900 you see how it starts to rescale and resize and then I can actually see it on live as I'm scaling just like you were on a browser the cool part fine you can design it's great but then what do I do with it well I can grab something I can go down here and it's basically giving me the DOM structuring cone, container, featured location and then oh remember that popup that I demoed the prototype this is the actual code that you get so that you can re-trade this design so you can actually extract the CSS needed to re-trade that part of the comp please work yep there you go oh yeah that'll save you some time has multiple pages I have to go on and on you have an about page, homepage so the moral of the story is fail harder that's my new motto basically try something try something until the wheels fall off and then pivot and then the last thing topco is this shameless plug for the new thing when I'm working on we actually extracted all of the UI the CSS from Reflow and we have open sourced it so you can get UI quality UI benchmarked CSS for your own applications it's an open source project we're actually looking for people to contribute it'd be awesome if you guys at least checked it out so I'm Christopher Joseph I'm Dan on Twitter this is the list of the links all the stuff I talked about that's a question that's really cool I'm wondering how come you decided to ship it as a desktop application and then also how do you like what's your workflow for shipping it as a desktop application okay why did we decide to ship it as a desktop application was number one why a desktop application well I think that designers currently we're just trying to cater to the way people work right now this also gives us the ability to maybe put it in the web someday if that becomes cool if this web thing has any legs to it let me rephrase how come you didn't ship it as a web application because we're trying to cater to what designers currently look for if I told the designer go to the web and start doing your design and they're used to Photoshop they might have a really hard time with that mental gap it might be really hard for them to wrap their head around not seeing designers are dumb I am a designer myself and I would have had a hard time doing it so I think we're just trying to give them a stepping stone towards the future without ripping the rug off them under them and be like deal with it and then the other part of it was how the other part you're asking what's the workflow like with that I'm curious what do you mean so you talked about building experimental web kit features like talk about your tool chain for shipping a desktop web application desktop so we have a team of kids adding new features design capabilities to the web kit and so they're pretty focused on adding features there and then we have Chromium which is the open source version that Chrome put out and Chromium has this really awesome thing called the actually I don't know what it's called but we are using a CEF which is the Chrome embedded framework and we've customized that for our needs for our evil deeds so we basically make a website I've developed most of the stuff just in the browser and then I cheated a little bit because I don't have to worry about all the other Firefox and IE6 I can mainly just focus on web kit specific prefixes and CSS and whatnot and then we compile it all together and launch it basically in its own browser just without any navigation so this thing totally runs without being downloaded as an app like it runs as a web application no what was the hardest problem you encountered when building this the hardest problem? oh man convincing people I wasn't stupid and I'm actually still not convinced that I'm bad but no it was that that was pretty hard I think perceptions were needed to be changed a lot but people were really willing to they were just kind of like tentative but technically the hardest problem I think we had a really big issue with loading and saving if you're going to be using the serializing features of backbone doing it from day one which was a big mistake on my part we weren't expecting to do it that way and all of a sudden they're like well we already you can serialize from that is that the way you want to do it let's go back and refactor everything so that was probably the hardest part so how does that work? yeah we use this proprietary file that's called JSON yeah yeah yeah so you had that special file that you loaded up so there's a whole bunch of JSON inside of that? yeah and a couple other things that we need for the shell but yeah basically so I have a question about whether you have any information or around the differences of how big your team was versus a team working on a native app within Adobe whether or not it was quicker to do it this way like any stats or any information you can reveal so we went from thought to product in 16 weeks I haven't heard of that happening I think from like an actual desktop inside Adobe that didn't happen before we went really fast I think we had a working prototype of the application in a week and we had a demoable prototype in 3 months that had most of the features that they wanted so as far as size of team it was 2 of us in the beginning Tara Fiener who is one of the best people I know on a really damn good developer and I were working on it night and day and then we scaled the team when they wanted to make it into a real product a real product to I think 9 people and that's about a normal size team at Adobe it's about 9 people and then they scaled exponentially as they add features but a normal startup team it's about 9 people sure yes I mean they're he asked if they were JavaScript devs it's um they're engineers and they know a lot of languages I'll be engineers at Adobe know multiple languages they're just good solid engineers and they picked up JavaScript better than me in a couple of days who's got the mic when do you expect to have a production ready version of Topcoat and also do you consider that the code that's output from Reclo to be production ready yes I believe we're using Topcoat internally now I consider all of the work that we put into the CSS for Reclo Topcoat alpha and all the terrible failures we learn from while doing that actually went into the architecture of Topcoat and so I think that it's I mean I'm making phone gap apps for the mobile for mobile it's ready for desktop we have to do some more work and expect again because mobile was prioritized higher because we our phone gap users were suffering a lot more than our desktop people weren't trading desktop apps with CSS so we kind of switched gears to our mobile because people were actually building a lot of apps with that so I think we're at .6 as of this week and I think by .8 we'll have production ready desktop just two quick things one it looks like what you're using to make it a desktop apps very similar to what the brackets people are using as far as the brackets frame I think they call it is that true it's exactly the same the brackets app shell and then two I just want to double check the rendering that's going on in that app is that actual DOM or is that some sort of like canvas rendering of DOM elements that you're using to do some sort of tricky you know enhancement stuff no the performance enhancements come from debounce and request animation frame it's awesome yeah so you said when you were prototyping you built it like you meant to test through the development right from the start doesn't that go against the whole point of prototyping does it? you built stuff quickly to prove a point go back and you build it probably interesting yeah so maybe I should expand a little bit on how I prototype so what I do is I make everything static especially web stuff I'll make a static version of whatever that pop over make a static version of that in HTML, CSS and then I'll start to add functionality to it right and so the functionality part I just test all the way through because otherwise I'm spending a bunch of time with buggy prototypes so I feel like I'm actually able to write code faster by writing tests so I think if the goal of prototyping is to make things really fast and prove them out I can prove them out and I can actually keep running with them once I'm done if I haven't tested them so I think there was a lot of emphasis when we were back in the flash days back in the glory days where there's a lot of emphasis on just like just bang it out dude no don't worry about it just bang it out just do it just do it and then they'd be like ok cool ship it I can't I just don't do that anymore I'm learning from my terrible mistakes so you mentioned at the beginning other teams at Adobe were kind of skeptical shall we say about using this HTML driven process how do things stand today I think I don't know I think it turned out pretty good and people are pretty excited about this new stack because it gives us a lot more opportunity I guess is the best way to put it we could make it a web app if we wanted to now with very little effort so they're seeing the benefits of it and the teams that were really skeptical were the ones that have just amazing edge anime is an amazing product it's a power tool all of the UI all the work they went into they all the work they put into all the UI they did a really really good job there's no way you could get this level of polish on an HTML and it was kind of a challenge I took it as a challenge and I think that they're happy without them no one really talks about that anymore so aside from saving a file or saving a desk and learning from a desk is everything what do you say everything beyond that is HTML5 and that's not described all of it so yeah and actually the sorry I was saying besides saving a desk and learning from the desk is everything HTML5 JavaScript and everything would run in the browser essentially it's using HTML save so yeah HTML the file saving so even that but it does have to go through a native layer you're right so we'd have to do some modifications for that part and give it up