 Yeah, I'm Mike, a little bit from Red Hat and a little bit blah, blah, blah, just to show that I'm an old fart in the project, working on medicines over 20 years now. And my expertise is in calic and itinerary framework. And so I instead of just copying from the release notes to the presentation here, I show one specific example of how I implemented a feature in calic, which is about table structure differences, which is a feature of Excel actually, where you can address the table branch in very specific ways when you get non-support. And 5.0, and in 5.0 we can read these things but don't write them back actually. And 4.0, 5.0, 1.0, we are writing back to the original works in Alipoma. So I'll just start with a short introduction into the formula compilation. So what's happening when you enter a new text to produce actually the code that the interpreter can read. So for a very simple example, we have some of a range from A to A4, which is 3.0. And we have two parses in the compiler. The first parser is to scan the text into tokens. So for each portion of text, identify whether we know what it will result in. And for each token we have an opcode and a setwarvenum, which is actually the type of token. And for each token there are also different token types defined so that to hold the actual information there. And each token is stored as a pointer and part of a formula token array, which actually holds the tokens there in the Picoat variable. So we have this sum, which recognizes the opcode sum and holds the open and the push and close. The push here, obviously push always means for the injecting value of the sum value or a range where a cannot place a value. And the corresponding types we have there. So SP byte in this case means for the sum function, there will be stored the number of parameters the sum function expects there. And as you said, there's no digital information and the SP database stores the range, the actual coordinates from A2 to A4 on the currency, for example. The close is also just a separate array. So we set two parses. So the next part is to create a sequence of interpretable tokens actually. So because the other form is just a tokenized form of what we can read. So the interpreter cannot interpret it without additional parsing. So we have to get this formula and then we scan this token area again. We have this opcode sum and the opening actually descends with the parser into the next level. And then we count as the push and the close again would go up at this stage. So in between, of course, instead of just a range, there could be another complex expression which did the parser there as standard and there were all the precedences by multiplication goes for addition, whatever. For this simple case, we simply ignore that. And we have, when we return from the level to the next high level, we store that opcode into the resultant token array and the same with the sum there. So now we have the sequence of the push and the sum which the interpreter can actually interpret and it takes the push and obtains the parameter from there and adds it to the sum function, for example. And this ends up in the arrays like this. And we have not complicated the actual tokens there, but the pointers are just the same, which has the pointers as stored in the arrays and actually point to the same objects there, which is actually a pre-commission for what we will follow next, how I implemented these things, because when we adapt ranges by inserting rows, deleting rows, whatever, moving arrays around, we adapt the references, for example, in the RPN array and automatically the normal token array is adapted as well because clearly it's called a shared. So we have a lot of challenges, volunteers, practical references. For example, this is a table here which has an optional header row and some data area and an optional total row. And it's a cell range that is defined to be a database range and in fact it can be actually accessed on the defined database ranges. So the table structure preferences is the syntax to address different arrays for sector table. And following the example always assumes that this table lives in the cell range A1 to B5. This is the other challenge. That is actually the definition of the OXML format. So that had to be implemented for these things. That's just for information you can read that later if you want to. It's an excerpt of the syntax that Microsoft published in their SLSX performance. So these are examples how such table ranges can be addressed. So we have always named tables. That can be an arbitrary name. That's just the defined other language there. And then within the square brackets there are prefix with a hash mark with items. So-called table reference items which can be all or data or headers or totals or a combination thereof. And there's also a special item, this row. This row always means on the row where the reference is written at the same row of the table. All these items of course can be translated and localized into various languages. So we also need total follows. We can't just literally. And separated by a comma in this case depending on the localization of course. Everything that is in square brackets does not start with the hash mark. It's a header name. So that can either be the cell content or there are even header less tables. It's possible where the actual header names are stored within this special stretch that is loaded from a full decoder. And in the last row you see for example, it also had arranges like possible, which is in this case header one to header two. That could be arbitrary header names within the table. So for each of these items we need of course some tokens. Which is here in the table name, which is already implemented or was already implemented before. It's a database range. We have this OCDB area. And the square bracket, the opening and closing, we need different upcodes of course. And for all the data tokens in this row we need the item upcodes and we have the already set operator and the range operator. And for the new resulting token reference we need the new token of upcodes table graph. So we have for example this formula here, a sum of a table range, which is the data range of the column which has a header header one. So when we parse it, I focus only on this table part here. The first table name is identified as an existing database area and it has a type SB index, where the index actually points into our known database area. It's the area number sum so. And when we parse the openings where in the bracket, and as soon as we do that, we know now the next bulk problems will be some table reference, some kind of table reference. So in the actually parsed or in this game token array, the OCDB array is replaced with an OCDB ref of the same next of course because it's still the same range and exchange with a special SB table ref token that holds additional information about the items and the resulting and so on. And I short cut this with OCTRO for the table ref open and just to have to short the line here, then we encounter hash data which is the data range of some table range there. And we know this is a table reference item and so store that item in the OCDB table ref column. We encounter it as a close to the separator and more openness and a header name. And the header name of course is sum offset within the table. So we can either calculate that from the store column names of the existing tables or find them in the cells if it doesn't exist yet. And in this case, only the column is important. So we just remember some reference in the column which here is always the first row defined database range. And some final closes there. When processing this table, actually we generate from all of these from the entire expression above so table, opener, hash data, closure, separator, whatever the result, the final result is just one with errors. So this is the normal opcode push we have there with the information this is a double reference with two coordinates actually and it is an A2 to A4 which then can be passed to the interpreter. So at the end we have again these two areas there but with the additional information that now for the OC table ref, this OC push we generated in the RPM is remanded at the SC table ref token. I mentioned earlier that when inserting or removing columns or rows installed the ranges are adapted. What we do now, if we adapt them in the RPM area the actual pointer that is that the share between these two areas reads that also the Apar token area knows about these things later which is very important because when we store this thing again in the old maximum alpha we will store the notation of the table structure to the parenthesis but in the ODF file these are not defined we have to store the actual range the resulting range so the reference continues to work but this table context is lost there and that's actually questions many. The syntax part is finished what is missing in storing the surroundings like the auto filter part and we currently are able to store the table context touch that X is able to read them and we can read it as well so the context is in the round trip and the table references continue to work in both applications so there are some details left to do Is there going to be the future in our own file format? Yeah, I think we have to extend more on something to go to where he says to get that into the formula differential Excluding the standardization part does it look like it would be particularly difficult to add support? Probably yes, no it's just actually currently it works that if for one syntax the table ref open is not defined that we store the old ranges and if it is defined we use the other formula differential references so it's just a matter of adding one line to one result for that tree Thank you