 Yes, that sounds like my microphone is working. Welcome to this last main-track talk. I'm going to speak about Caligra, and I was asked to make this talk as technical as possible, so you will see C++ codes on these slides. Let me first introduce Caligra. The name Caligra might be rather new to you, because it's a new name, but it's a name for a project that's already quite old. It started over 10 years ago under the name of K-office. Caligra is an application suite that comprises both productivity applications, as well as creativity applications. That's how I came in. I'm not one of the maintainers of the productivity applications. I maintain the painting application, Krita, which is just one of the many applications in this suite. Caligra is being developed by 30 to 70 people. It depends a bit on how you count, who you count. Additionally, several companies are interested in the development of this software. My own company, KOGMBH, was founded by me, by another guy from the Calves community and some other people. NoCars is interested in using Caligra in their mobile devices to provide office document functionality. There are other companies around the world that use Caligra. There is a Vietnamese company I've heard about, because they joined us on ISE and asked a couple of questions. They are doing something tablet-related, but we are not exactly allowed to know what. There's a German company, which uses the word processor inside a medical further application. Doctors walking around in a hospital and taking notes on their patient forms used in Caligra. There is a company in London, which integrates it in their financial application. The thing is, and this is what Caligra can do for you, if you are developing software that needs office document compatibility, editing and viewing, then embedding Caligra as a component can give you a head start. In our community, we often say what we are aiming for is not just a set of really cool desktop applications. That's one thing we are doing. We are making desktop applications. They are quite cool. We are also trying to sort of become the webkit in the office document arena, where if you have an office document and you want to do something with it in your application, on your device, your form factor, you can just use this component and go. And that's what I'm going to show in this presentation. First, I'll give you a short overview of the architecture of Caligra, and then we will look at the different ways to embed a Caligra component in your application. So, some history to start with, because it's often said that we are often asked, why are you working on yet another office software application? There are others, and they were already free. I think the very first free office application was the Andrew Street by the Carnegie Mellon Institute. It's on the top left. I'd actually supported embedding pictures tables en ben het e-mail. Het was wel cool, maar als software gaat, was het heel, heel hard te gebruiken. Dan hadden we iets called CIAC-office with a word processor called Pathetic Writer. En dat software is sort of petered-out. Deze applicaties waren al in existence when around 1997, 1996, people inside the KDE community started thinking about creating a full-featured free office solution. A couple of years later, open office was free. What do we have in Caligra? The screenshot you see is really cool. That says the office application running on an N900 mobile phone. Nokia would like me to call it a mobile computing platform. Het supports presentations, spreadsheets, word processing documents you can add it. It's called all kinds of fun features like being able to use your phone while giving a presentation and shaking it, and then you will go to the next slide. I didn't dare do that here. The other applications in Caligra are word staging tables. Those are word processing, presentation. I'm using stage here to give my presentation, and it hasn't crashed yet. Tables, spreadsheet, plan. It's a project planner. Flow, a diagram application, which has been dead for a long time. When we moved from KDE3 to KDE4, from KFS1 to 2, a couple of applications really fell by the wayside. The maintainer was too busy. No development done anymore. But these days we've got a new guy working on Flow. He's from Beijing, and he will join us at our next Caligra developer sprint. So there's a really good chance that this application will be back in the next release. And then, actually, it's a database application. It's kind of like Microsoft Access, but cool. So what's the basic architecture of a Caligra application? I'm going to use this screenshot of our vector art application, Carmen, to show you the basics as they are shown to the user on the desktop. We've got a canvas. The big difference between applications in Caligra are not the individual code basis, because we share a lot of code. All the objects you see on screen are small, fine-grained objects implemented in plugins that every application can use. This vector graphic, you can embed it in a Word document. You can embed it in your presentation. You can embed it in your spreadsheet. You can embed it in your Raster Graphics art in Krita. The difference between these applications is the canvas. So, for instance, a Word Processing application has this long, long, long list of pages. And every page has text and a header and a footer. On the canvas is shown as a long list. A presentation is slides, so you have lots of different slides and they are all shown separately. A spreadsheet has got sheets, sheets possibly infinite in size, although that's not really practical at the moment. And those sheets can be stacked as well. Those are the real big differences between the canvases and so between the applications. Many places in Caligra, we have tried, and this is one area where we are still looking for the really, really correct user interaction design, but we've tried to make it similar for all applications. You've got your canvas. You have a bunch of tools with which you manipulate the object on your canvas. And then you've got a list of panels that show you the current settings of your tools and of your objects. Finally, all Caligra applications are still k-parts. The k-part technology is close to what liberal officers, as you know, what Microsoft officers are already embedding. What it used to be was we embed a whole application canvas inside the canvas of another document. Everyone will probably have seen this screenshot of a Microsoft Word document with a Microsoft Excel document and that is a table. That principle, we've dropped. So you do not embed whole documents in documents anymore. That does not mean that the k-part embedding technology has been lost. Every document is k-part, so you can embed your canvas as a k-part in another application. And we will discuss that some more later on. So what is Caligra based on? Caligra, as an application, is not written from scratch using just C++ and standard library. Because we are using, as our foundation, some great platforms, we were able to reach the current state of functionality with all these applications included in under one million lines of C++. And I'm quite sure we can even get rid of a number of those as well because if your application is 10 years old, you are going to have some cruft. So what are we using Qt for? Qt is our main GUI platform, but Qt is more than just a rigid library. It provides our platform abstractions. It provides us with threading. We use threading a lot. It provides our XML handling. And it provides, and this is quite unique, our text document architecture. What Qt provides is a complete rich text document abstraction where you can add paragraph by paragraph, style by style, table by table, a complete and long text document. And that's the basis of what we use in our text component, which is, again, shared among all applications. The work process uses the same text component as the roster image editor. This text document can then be layouted. And there's an abstract layout engine, which we have subclassed in Caligra to provide more precise layout. Qt is the lowest basis we use. On top of Qt, we have KDE. And KDE is not optional. We use KDE, for instance, for plugin loading. And Caligra is heavily based on plugins. Even the text layout component, the text component you type text in. Even that is a plugin. If anyone thinks I can make a better text layout plugin, he just has to implement the interface and then the functionality, which is a bit more work. Scripting, scripting is done using the cross library, which means that if you want to extend a Caligra application with a script, you can use any language with cross supports, which is Python and Ruby and Perl and Java and JavaScript en even something called Falcon. We use it for JobCube, which is another form of threading. For instance, printing is done in the background using threading. Then we use it for settings, which is sort of a hot topic these days, since Ubuntu is busy writing yet another settings library for Qt. We'll see what happens to that. For now, we use Kconfig and are happy with the performance of that. We use it for the translations, the internationalization. KDE, everyone has an opinion on KDE, but if you go and talk to a mobile device manufacturer, their opinion of KDE is, it's too big. Initially, what we did when Nokia wanted to put a chaos-based mobile office viewer on MIMO was to cut down KDE en kut away all the code that wasn't directly used. So most of it is just stubs. It's a fork. It's MIMO specific. If you want to use Caligra in your application, your device, your form factor, whatever you want, my advice is do not touch LibCock with a very large barge pool. Keep away from it. Then there are two other possibilities. Just use plain KDE, like your Linux distribution packages, like it's packets for Windows. People complain and tell you it's big. It's really just 40 megabytes. Just compare that to the size of your SD card in your camera or your phone. Using plain KDE has the advantage that you are binary compatible with official releases. However, there's another option. That's the KDE mobile profile. It was created by KDEB and KL people. KDEB is a German company focusing on KDE technology. And K.O. is also a German company focusing on KDE technology. What we did together was go through off KDE and remove everything that's deprecated. That's still there to be compatible with source code written in KDE in three days. That's still there to be compatible with ideas that we've long since discarded. KDE mobile profile is also KDE cut-up into smaller parts. Big libraries have been split up in small functional components for you. Only need to take what you need for your application. And that's surprisingly little for Caligra. Caligra is a big, big KDE application. It uses a lot of technologies. And still we only need 11 megabytes of supporting libraries. What we use this for is platforms like Mego. Mego for netbooks, Mego for handsets. This is really suitable as a platform to build on for the future. And if you are making a Windows application, and that's Caligra technology, and want to create an installer. And I know of at least two separate cases where that happens in a big environment with many hundreds of users. Dan had also compiled a mobile profile of KDE. The mobile profile of KDE is not a fork. It's right inside the KDE Git repository, which was created last week when KDE moved from Subversion to Git. This is the dependency graph for the Caligra mobile application. The Caligra mobile application is the same as Free Office for MyMone. The top half is what Caligra uses. The other half are the KDE libraries. We actually really need KDE Core, KIO for IO, which is Network Independent, Kparts for embedding, because still every Caligra application is a Kpart. If you use a document in Caligra, an Office document, then you have a Kpart. And some other stuff like Solid for Hardware, Retrognation, KSM Utils for Settings, Notifications, mainly for the Spreadsheet module. En dan is er een host of other dependencies. Most of them optional, fortunately. Some of them used by only one or two applications, like OpenShiva, which is really, really cool technology to write pixel transformations. MyPetProjectTreater uses that. But this is to show that this is not a huge standalone application with tens of millions of lines of code where everything that was not invented here is invented here after all. We are not afraid to use other people's technology. And I think that's a good thing. It does give some headaches for packaging for Windows, though. So these are the four big, big parts that make up Caligra. And I will be discussing them here. We have what we call shapes. Shapes are really small, fine-grained objects that combine data, a way to represent the data, and a way to load and save the data. We have a canvas. A canvas represents your pages for the particular kind of document you need. All these are shapes. And actually, this is two shapes in one, the chart and the labels. Dan we have the filters. The situation there is getting a little bit unclear these days. But one firm principle was that a filter in Caligra is independent of the application it filters through. So if you filter from a Microsoft Office document, what you get is an ODF document. And the ODF document is what the Caligra application reads. That works fine for presentations. It works totally fine for text. But we were running into performance problems for spreadsheets, for really big spreadsheets. So we had to let go of that principle a bit. And then there's plugins. Plugins is just a big basket of things that we don't code into the core. Like color management. Color management is evil for text documents. Quite important these days. If you create a text document you want to have it professionally printed, you have to have a color managed image. So we have a color management library based on little CMS. But the dependency on little CMS is optional. That's encapsulated in a plug-in, a color engine plug-in. Our tools are plug-ins. Our shapes are plug-ins. Most of user interfaces plug-ins. If you look at an application like Caligra tables you will see options for sorting and filtering and data handling. And most of those are plug-ins dat use de KDE, Component Technology, K-part, which Michael Meeks says does no longer exist. But it does use that specific technology to combine those plug-ins into the query that make Caligra tables for you. Code layout. What I hope is that all of you will be checking out our Git repository start hacking. So I'm going to tell you where to find which bits of code. There's the libraries. The libraries contain the Flake library, which handles those shapes. It contains the text library which loads ODF text and styles. It contains some supporting widgets and it contains the main document application fewer controller abstractions. Then there are all the applications in their own directory. And most of those applications have sub-directory called part, which implements the K-part. Then there are tools. The tools are, right now, but that's just an accident. One of the tools is the Caligra mobile application. It should be moved. But it contains scripts to handle our document, test document repository, to find test documents on the web, to do standalone conversion. Caligra has a huge repository of real-life documents that we test against every commit until we break the build server. Plugins, that's where you find all those plugins. And filters is where you find all the filters that create open document or give an open document, create an export format. This is something I have to be quite honest about. Our input filters really are good these days. They have improved a lot. We have good support mainly for the Microsoft Office document file formats. We also have good support for some other file formats. We don't really have export filters anymore. Most of them got broken and they haven't been repaired and that's going to take a really huge effort. And we haven't embarked on that effort yet because mostly people are interested in loading their documents and reading them. We don't know what will happen in six months. So let's look at what the filter looks like. The filter is really simple. You have a desktop file and the desktop file defines which mind type you go from, which mind type you go to. And then in your implementation, you implement a convert function that takes us, arguments, those two mind types from and to. And then now and then you tell the application that you've made progress in your conversion otherwise the user will think your application will hang. This is more or less a filter. So be defensive. Check that you indeed got documents of the right mind type. That's the first part. Then get your input and output files. Chaos in caligar can chain filters. So you can go if there is no direct conversion from one mind type to another, but there is an intermediate format. We can go through the intermediate format. That's called the chain. We get the input file and we get the output file. We have to read the name of the file we have to write to. We create a chaos store, which is a file system abstraction on that file, which we are going to write to. Then we write the interesting bit of code. I put it in the comment here. That can be really complicated, especially if you look at the older established office formats. And then we close the file. If that succeeds, we return okay, and everything is okay. We've just converted the document. The bit that I've commented out is really the interesting bit, of course, but that you will have to do for your own filters. Shapes. Document made up out of all these small shapes. Because you don't know when you start out which shapes you will have, which shapes you will need. Shapes are plugins. In order to make it possible for the system to find which shape to load for which part of open documents. We have this support function in a shape factory. The shape factory will create shapes. So what happens is we go through all the factories that are registered in the system one by one and check, are you supporting this type of ODF element? En dan, one factory says, yes, I do, I do, I do, I do. Give me a chance. Then we call create a default shape, which is just an empty version of that shape. And then, on the shape, we call load ODF. And the shape populates itself as the data and is now ready to be used, shown or edited. So what does the shape do? A shape loads itself, paints itself. And then when asked, it will save itself. To ODF, that's what we do in our core. When all these shapes are loaded, your document is created and you see your document, you want to do some stuff to it. Remove text, add text, paint on it. And it can get quite complicated because these days people have a mouse. We have to send mouse events. We have to send stylus events if you've got a graphics tablet. We also got creativity applications. And then if you've got a graphics tablet, you might as well have two input devices. You might have an art pen and a stylus. And we keep track of all those. So what happens is, the system sends to your application window, they go to a widget or a graphics item. They send it on to your canvas. Your canvas sends the event to a tool manager. En the tool manager checks, wait, this was a mouse with this ID. OK, and I haven't seen it before, so I create a new tool instance and then the tool can handle the event. So we keep track of all the input devices the user has used and for every input device we create all the tools the user has wanted to use. Now, what is a tool? A tool is not just something to manipulate a factor with. A tool is also a thing you use to enter and delete text. So our text component, which is, again, a plug-in, is a shape, has its own tool, the text tool. And when you activate your text box on-screen, the text will get activated, you can type and select styles and create both an italic text and delete text and search, et cetera. So the whole concept of tool is really, really quite wide here. En dat also means that the interface of a tool is really big. This is just a subset. Again, a tool can paint itself on the canvas. Because if, for instance, you want to drag a box on-screen, you want to show those rubber bands. If you want to select something, you want to show rubber bands, if you want to paint a factor, you want to show something, if you manipulate a grid, you want to show the grid. All that is tool decorations. Dan, a tool has option widgets, because the action of a tool is sometimes different. Something like that. And a tool has to accept all these mouse events, mouse press event, tablet event, enzo on, enzo on, enzo on, enzo on. I've just put the mouse press event in there and all the other events. And then a tool knows about the data that's inside the shape. So sometimes tools are really quite specific to a particular shape. Text tool can't do anything to a path shape or a chart shape. So a tool is also used to implement cut, copy, and paste from the content of a shape. Cut, copy, and paste of the shape itself is handled on a higher level. So where are we, right? Telegra, your application. I just couldn't resist including the screenshot, because this is cool. So on finally managed to fix all the Linux essence, all the GCC essence today, and managed to make Kalligar compile on Windows again. We're all working on Linux. We don't really give... We don't really care much about Windows. Or OS X. But there's this guy and his Linux laptop broke down, so he had to use his work laptop and he wanted to hack on Kalligar anyway. So this works. But we've also... I also know a company that uses Kalligar embedded in their own Windows application. They also develop on Linux because what self-respecting developer would want to develop directly on Windows these days. But then they have to build it for Windows. So I'm really happy for them that we managed to fix this. If you want to embed a Kalligar component, a Kalligar canvas in your own application, there are basically three strategies. At this point, I have to admit that there is something wrong in the realm of Kpart. Kpart embedding is the oldest component technology in KDE. It's what used to be used when you were running Conquer and you would browse the web and click on a document and then the document would be shown embedded in your browser. I still think that was way cool. It still works fine for Kalligar works. But when I tried for this presentation, I'm afraid it was really broken for tables and it was mostly broken for stage. That it is broken doesn't mean it won't get fixed. I think we should fix it. That's your first embedding strategy. What happens if you do that? You have to have a K application. You have to have a K main window. And then your whole central area of your window will be taken by the Kalligar application. The Kalligar application will merge all the menus in the menus of the hosting application. It will try to merge the toolbars. It won't merge unless you use a K main window, the dockers and the toolbox. So editing will be tricky. Well, I'll have to do some work for that. You'll have to use a lower level interface to access the tool or even the document directly and perform changes if you want to have reading and writing. The second embedding strategy is a bit of a hack, a really cool hack. But it's a hack. It's QWitchit-based. I don't know whether how many of you guys are Q'd developers and are up to date on what Nokia is doing these days to Q'd. Basically Q'd used to be based on Wichits. Wichits are on Windows, Windows, they have a window handle, on X11, they are Wichits. That somehow doesn't scale to creating nice, animated, flipping, old dancing applications like we like to see these days. So what did they do? They took a perfectly fine canvas abstraction, Q GraphicsView, which was originally created to create huge canvases, mostly for industrial applications. Like if you were going to create a mapping application that would implement a map of, say, all of the Netherlands with all the streets and wanted to do traffic simulation on that Q GraphicsView was the perfect solution. But it could also animate, which is for traffic simulation also quite nice. But they then created a Wichit library on top of Q GraphicsView. They called it Litmigo Touch. It's deprecated by now, but it's still based on Q GraphicsView. So by now Q'd has two ways to handle Wichits. They have your ordinary QWichit and they have the newfangled already deprecated Litmigo TouchWichits. De very first time we tried to embed Caligra into a mobile application, we used QWichit because this was for MIMO, for Freemantle. It didn't have the fancy Q GraphicsViewWichits yet. So what did we do? We grabbed our Caligra application, we grabbed the main view. It's a model view controller system, so we grabbed the viewWichit and in the viewWichit we grabbed its childWichit, the canvas. So we would lose all the decorations, manual bars, toolbars around the main canvasWichit. We would hide the parent viewWichit, take this canvasWichit, which we were really happy to have, and put it right in a new parent. That's what free-office users of MIMO Freemantle. It's really easy to do. It is a hack, but it works. It's totally okay to do it that way. Last summer, Nokia had more than a dozen interns in Bangalore working on extending free-office for MIMO with way-cool plug-ins and editing capabilities. And these guys, they were really brilliant, really good guys. They took this code base and took it places where you would never expect of it. Like the shaking thing I mentioned, but also direct block support. New type in your free-office on Calico Mobile, your block entry, press a button, and it's there on blogger.com. Anyway, this is what we used for free-office. Dan came Lipnico Touch and Qt Quick, QML. For that, we really needed to have a canvas that supported Q-graphics items. So what did we do? We abstracted away the hard-coded widget dependencies of the Calico Canvas code and we created another Canvas type based on Q-graphics widget. And that you can embed in a Q-graphics view or in a QML, QDeclarative application. That has yet found that it's really flexible. You can do nice animations with your documents now. Let me see whether I can show it. This is just a test application. Kinetic scrolling, stuff like that. Zoom in, zoom out. That's a kind of card tables application, but it's got a complete new UI. And this, by the way, this, no, this. Where did my application go? This one. Free-office. That's my presentation in free-office. It uses exactly the same presentation component. But in a user interface, this is running on my desktop. I just compiled it on my desktop. But if you compile this on a tablet or for your mobile phone, you can scroll and flick with your finger. The buttons are big enough to be finger-usable. So across all these form factors, mobile devices, tablets, netbooks, desktop applications, a huge variety of desktop applications. You can still use the same engine. And that's a really unique capability. Of course, it's early days. We are learning as we go. The interfaces haven't really, really been set in stone yet. There are still some problems where you really have some difficult issues to fix, to work with. For instance, if you don't want to use the text tool to manipulate text, you have to use the text document, the text editor interface. That can be tricky. If you want to implement your Qt-Caligra application, you have to have a way to tell the canvas when to zoom and when to scroll. That can be tricky as well. So the main integration point for your application en the Caligra engine is the canvas. A canvas shows what's in a document. Right here you see one limitation almost immediately. One document can have more than one view and one view can be shown on a widget. Right now it's not possible to show your document in more than one graphic view. So start with the document. You've got a file you want to load. A simple text file. Dan we check what the MIME type of the text file is en we ask the KDE plug-in system, which is very sophisticated, to give us an instance of the document class that can load this file. All Caligra documents are based on KO documents. So that's the class we are going to get. We haven't opened the document yet. We just have an instance of a class which comes from a plug-in. So the list, the set of documents we can read is extensible. We just have a document that's empty. Now we want to load it. We load it from a URL. Loading from a URL means we are loading it network transparently, whether you want to load from the hard disk of your laptop, or whether you want to load from a website, it will work. When we have the document, at the moment when we have the document and have the document loaded, we are still completely free in what we want to do. Want to go for k-parts? That's possible. Create a main window, which is a k-part main window. You have to set class that. You have to implement some methods. They are all quite clearly described in the API documentation. Then create a GUI from your part. The KDE k-parts technology is smart enough to have a generic create GUI that takes your part, which is our document, and creates a GUI from that and embed it. This technology has worked since KDE 2 with minor variations and API changes. If you want a few instead, and you've got your loaded document, then you tell your document, create a few. And then you've got a widget, a k of u is a q widget, which for now is invisible. You also need a q main window, or a k main window, or an m main window, depending on a particular variety of platform you're using. You simply grab the canvas widget out of the few and set it as your central widget. And then you've got your document. It's shown. It will even scroll already. It will even zoom, although you might have to implement some actions in your application to connect to the zooming functionality in KL View. QL, Q of Graphics View, is a bit more complicated. You get your canvas item from the document, same as you would get a few. And then you have to, oh, that's the typo, you have to implement the KL Canvas Controller Class. The KL Canvas Controller Class is quite big. It's a huge interface. It's relatively new, so it's not entirely well documented yet. And it is responsible for all your scrolling, panning, en zooming needs. And it needs to be the thing that is shown in your application because your KL Canvas Controller is the first thing that gets the event. It needs to know somehow which events have to go to the canvas and which events it needs to do the scrolling and zooming. So, KL Canvas Controller, you set your canvas, which we just got from a few on the canvas controller. And then you have to integrate, implement these methods and integrate them with your application's user interface, scrolling, panning, zooming, zooming, en zooming. The proliferation of zoom methods is a ward in our API which we really should fix. But that's what you get when you develop software iteratively. These are two examples. I've already shown them live of applications where you can use your, where you can take your need for an application, your need for a user interface en create a customer application. The uglyness in menu bar is because this is a mobile application compiled from my desktop. So, where do we want to go from here? I think it is already quite, quite successful. There are tens of thousands of people who have used this in their N900s. I'm fairly confident we will see it on other mobile devices. We will see it on other desktops. But what are the problems that are left that we need to solve to make this really the webkit for the office document world? It's still really quite difficult to really dig in. This presentation just scratches the surface of what you need to do to implement your own category-based application. On the other hand, that's good. It's good that our APIs are not yet finalized, that there is still wiggle room for people with special needs, which makes this the perfect time to actually join this effort and take care of places that I haven't thought of yet. Telefissions could be good, other desktop applications. I'm sure that if someone feels that, oh no, this whole tools, dockers, paradigm, that sucks for desktop. It's totally fine with us. If someone takes the Caligra engine and builds a different paradigm on top of it, that's what the engine is for, to make it possible. We actually didn't realize that when we started working on Caligra in 2006, when we had a meeting in my place in the Aventure in the Netherlands with four or five K-office hackers. We sat down on what do we want to make? We want to make something flexible. We want to make it possible to create different user interfaces, but at that point we put the cut too high. We thought if you create a different user interface, you're going to create different tools, different dockers within the same basic applications. Now we know we have to be flexible at all levels. Even our filters are reusable. If WebODF gets integrated in a good many places and people want to use it to view Microsoft's binary formal documents, they can use KL Converter to convert to ODF. Read the ODF in WebODF, write the ODF back when your system is right, editing implementation, and then convert it back when somebody else is done with our Microsoft Format export filters. Because those are not done. We used to have an RTF export filter. There is rudimentary XLS export filter, but this is something that needs to be done right. When we started, again, looking at the import filters, we started with the PowerPoint import filter. PowerPoint is used a lot. And we wanted to have good support for it. The PowerPoint import filter was written during the Google Sum of Code project in 2007. En it was not easily solvable. The original author had left. The codebase was, well, not too large, not flexible enough. So we grabbed the bull by the horns and took the decision to rewrite it from scratch. Well, when I say rewrite, to generate most of it from scratch. Back then, good documentation was rare. These days Microsoft provides good documentation. En while personally don't have much use for Windows, I have to commend Microsoft in a way they have cooperated with us in the past year. They have invited people from our community to Seattle and have discussions with their implementers. And we've been able to help them in a small way. Marine Cross will bring our category tables maintainer managed to fix a Birken Excel in the import for all the type Excel filters. So that's where we are these days. The future is hugely exciting, I think. Can a car can spread and can become a really ubiquitous component. And that's going to be fun. Thank you. Thank you. We have some time left for questions. Are there any questions? I don't see anyone raising their hand. Oh, I guess there are no questions then. Well, thank you again. I hope I wasn't too technical.