Board index FlightGear Development Nasal

Why not use Erlang instead of NASAL?

Nasal is the scripting language of FlightGear.

Re: Why not use Erlang instead of NASAL?

Postby Johan G » Mon Oct 10, 2016 1:28 pm

Thorsten wrote in Mon Oct 10, 2016 6:17 am:
abassign wrote in Sun Oct 09, 2016 9:54 pm: the idea that with a few lines of code you can generate interfaces that can, with efficiency, replace the XML and NASAL without reducing performance.


Ah - magic...

+1 ;)

The verbosity of XML have both advantages and disadvantages, but in the end it is near impossible to give a detailed (human readable) description of complex specifications, systems, relationships, interactions etc. without a certain level of verbosity.

The same of course applies to any scripting language. In the end you would still have to do nearly the same interactions with nearly the same data.


I think that in the long run it would be more efficient to focus on multi-layered documentation (end user|aircraft/scenery/etc developer|core developer) and more importently the software architecture (which in turn also requires documentation, but probably also test harnesses so that people dare touch the code).
Low-level flying — It's all fun and games till someone looses an engine. (Paraphrased from a YouTube video)
Improving the Dassault Mirage F1 (Wiki, Forum, GitLab. Work in slow progress)
Johan G
Moderator
 
Posts: 5292
Joined: Fri Aug 06, 2010 5:33 pm
Location: Sweden
Callsign: SE-JG
IRC name: Johan_G
Version: 3.0.0
OS: Windows 7, 32 bit

Re: Why not use Erlang instead of NASAL?

Postby Hooray » Mon Oct 10, 2016 6:04 pm

At some point, Nasals' primary/only mechanisms to deal with any FlightGear code were the property tree and so called fgcommands:

http://wiki.flightgear.org/Property_tree
http://wiki.flightgear.org/Bindings

In addition, Nasal comes with its own standard library of functions implemented in C, including an API to expose existing C/C++ functions to Nasal (and vice versa)

The corresponding mechanism is documented at: http://wiki.flightgear.org/Howto:Extend_Nasal

Meanwhile, this mechanism can be considered to be a legacy thing, because it's been wrapped by a high-level implementation, called "cppbind", this goes beyond just exposing procedural APIs in the sense that also fully object-oriented APIs are exposed (think classes and objects): http://wiki.flightgear.org/Nasal/CppBind

The CppBind framework is primarily, and extensively, used by the Canvas system and any code related to it, including some non Canvas code written by the same developer (TheTom).

What you're hinting at, and what sounds like "magic" to some (admittedly there IS a language barrier) could be best summed up by pointing you to SWIG.
Note that SWIG is supported by Python (and many other scripting languages, including Perl and Lua), and that an outdated adaption for Nasal does exist.

Nasal the language, and its integration are documented in the repositories - e.g. the original 2004 document still being here: https://sourceforge.net/p/flightgear/fl ... Nasal.html

The most recent docs created by Andy are kept here: https://github.com/andyross/nasal/tree/master/www

In addition, $FG_ROOT/Docs contains a rather extensive technical overview about some of Nasal's internals, written by Philosopher and myself: https://sourceforge.net/p/flightgear/fg ... format=raw

Regarding SWIG (it not being magic), in the light of multicore hardware and distributed setups, the real power lies elsewhere, i.e. in some form of IPC like HLA (or even just Emesary)

Besides, as a matter of fact, even predating the whole IPC idea, we did have full APIs modeled on top of the property using merely the notion of listeners, which is very much superior to low-level scripting bindings (even in the SWIG sense), because those are inevitably language specific, and add to our workload - whereas subsystems like the AI system (or even Canvas) are fully scriptable without any of the underlying C++ having to be aware of it, just by abusing the SGPropertyChangeListener API to model a complete API on top of the property tree, where you can tell C++ code to do something for you just by creating/updating properties in a well-defined structure using certain naming/typing conventions and a certain hierarchy - for instance, that is how the bombable system gets away with using Nasal scripting to exploit the AI system, despite it not containing a single line of dogfighting related code - and despite it not having been significantly maintained/updated in years.

Basically, imagine a listener-based API modeled on top of the proeprty tree to be like a remote control that doesn't bother who presses the corresponding buttons or for what reason - in fact, it usually doesn't know anything about its "user" other than that there is a mailbox with a few envelopes containing instructions that it tries to parse, and if they make sense, it changes some internal state and so on

One of the key lessons to be learnt from this is that FlightGear could/would be in excellent shape, regardless of Nasal if it had more subsystems using primarily/solely the property tree to expose internal APIs for arbitrary purposes - because at that point, the concrete use-case no longer matters, which is why Durk's original AI code can be used via C++, Nasal - but also via httpd (Phi) or telnet (props).

Equally, you can render/create and update a Canvas texture without necessarily having to use any Nasal code - simply by directly modifying the property tree.

Which is to say that _any_ existing subsystem using this approach can automatically be used from another scripting language that exposes the underlying API, aka the FlightGear property tree - which I understand, bugman's FGPythonSys is already doing (?)

In other words, if a subsystem can be used/controlled via the property tree (browser) and/or telnet, you can also access it from any scripting language that has property tree bindings.
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 11119
Joined: Tue Mar 25, 2008 8:40 am

Re: Why not use Erlang instead of NASAL?

Postby abassign » Tue Oct 11, 2016 7:30 am

Johan G wrote in Mon Oct 10, 2016 1:28 pm:...
I think that in the long run it would be more efficient to focus on multi-layered documentation (end user|aircraft/scenery/etc developer|core developer) and more importently the software architecture (which in turn also requires documentation, but probably also test harnesses so that people dare touch the code).


I thank you for having precised this aspect of the problem, the lack of adequate and well-organized documentation makes it difficult, if not impossible, the possibility of others to participate, modify and improve the code.
Certainly FGFS is a simulation environment that has undergone various transformations are not always well designed and this shows! Certainly some of the kernel programmers are trying to bring order, but does not seem very successfully. The problem is that before would have made an effort to improve the documentation by those who know the code. is not possible to say that one must study it for a long ... a long time ... before do something! In a company that situation almost always leads to the rewrite of the entire code, is cheaper in hours of development and at the same time introduces the modifications required and often, always at the same time, produces a proper documentation!
It would require that the kernel developers would stop in their work and to writing proper documentation. Within a few months I am sure that the whole project would gain, new developers could enter the project attracted by perception of being able to handle it.
I notice that currently the programmers of the code are very verbose to give the idiot who asks questions on the structure of the system, of those who want to introduce new methods of approach that are not those of them conceived!
Instead of wasting time to give the jerk, lose their time writing proper documentation and will notice immediately that the "stupid" questions will become increasingly less, and useful contributions on improve the project grow up, however, because many of FGFS fans are programmers , 3D graphics, pilots, meteorologists! FGFS has a great heritage of people who can make this project up to challenge X-Plane & C. But this is impossible if at this time only a very few are able to "get their hands" on the kernel code.
Continue to read the documentation that is just rewriting the post in the forums I find it totally inadequate, the documentation should be done methodically and attention and should be the element that allows the admission of the code on the system code level. To be precise only if the new function has a proper documentation it can be moved from experimental to operational levels! This way we avoid seeing thousands of lines of code with a banal documents, encrypted, detached from the context.

For example thisi is the JSBSIm documentation:
http://jsbsim.sourceforge.net/JSBSim/index.html

Nothing fancy, and of course it is easy to make a documentation of a unique program, compared to a set of modules conversing in various ways as FGFS.

So I think the first thing to do would be to create a framework connection between all modules and the related flows, so that you have a kind of "map" that allows each of us to be able to figure out where is inside code. Start from a new Wiki that is appropriate for the system documentation, unlike the current Wiki containing everything so is confused and often out of the context of use.
I know it's hard, but this work should be initiated by those who already know the code, otherwise this becomes "a cat that wants to eat the tail"!

A greeting to all! :)
abassign
 
Posts: 725
Joined: Mon Feb 27, 2012 5:09 pm
Location: Italy (living 5 Km from airport LIME)
Callsign: I-BASSY
Version: 2018.3
OS: Linux Mint 19. x

Re: Why not use Erlang instead of NASAL?

Postby bugman » Tue Oct 11, 2016 8:53 am

@Abassign: Do you know that the core developers rarely, and for many never, visit this forum? Did you know that in most open source software, that the design documents are the technical discussions in the mailing list archives? Are you subscribed to the FlightGear development mailing list? And did you know that established codebases are absolutely always more difficult to work with compared to writing new code, in all software projects, open or closed?

Regards,
Edward
bugman
Moderator
 
Posts: 1524
Joined: Thu Mar 19, 2015 9:01 am
Version: next

Re: Why not use Erlang instead of NASAL?

Postby abassign » Tue Oct 11, 2016 10:54 am

bugman wrote in Tue Oct 11, 2016 8:53 am:@Abassign: Do you know that the core developers rarely, and for many never, visit this forum? Did you know that in most open source software, that the design documents are the technical discussions in the mailing list archives? Are you subscribed to the FlightGear development mailing list? And did you know that established codebases are absolutely always more difficult to work with compared to writing new code, in all software projects, open or closed?


You're right, but how many are currently active on the kernel developers who have not read this post?
I think very few, when I read the technical forums are almost always the same reading in this area :(

However, my provocation is now moving on to a subject that is developed in other contexts, including the one you mentioned in your post. And to think that my question was simple, but still has not found a clear answer ... ;)
abassign
 
Posts: 725
Joined: Mon Feb 27, 2012 5:09 pm
Location: Italy (living 5 Km from airport LIME)
Callsign: I-BASSY
Version: 2018.3
OS: Linux Mint 19. x

Re: Why not use Erlang instead of NASAL?

Postby bugman » Tue Oct 11, 2016 11:05 am

Maybe for a clear answer, you need to start with a clear question ;)

Regards,
Edward
bugman
Moderator
 
Posts: 1524
Joined: Thu Mar 19, 2015 9:01 am
Version: next

Re: Why not use Erlang instead of NASAL?

Postby abassign » Tue Oct 11, 2016 7:17 pm

bugman wrote in Tue Oct 11, 2016 11:05 am:Maybe for a clear answer, you need to start with a clear question ;)


I want to fly a plane from an airport without using the XML and neither NASAL. But only using the commands allowed by the Telnet TCP / UDP connection! If this is possible then it is possible, simply, interface any language, including the incredible Erlang.
Right now I am not interested efficiency, I want to know how it actually works and how the code is layered.

If unable to ... then it is also a problem for the other languages, it means that he FGFS within the code, there are programs that are not based only on the tree of the properties.

I hope now that everything is clearer, who takes up the challenge, maybe someone has already done it ... who knows ?

In exchange, if it were possible, I promise that I make a special documentation on the current Wiki, which I hope tomorrow can become a technical wiki for those who want to challenge themselves in the development of the code.

Saluti :) Adriano
di FGFS Italia su FaceBook
abassign
 
Posts: 725
Joined: Mon Feb 27, 2012 5:09 pm
Location: Italy (living 5 Km from airport LIME)
Callsign: I-BASSY
Version: 2018.3
OS: Linux Mint 19. x

Re: Why not use Erlang instead of NASAL?

Postby Hooray » Tue Oct 11, 2016 7:38 pm

you should consider posting in your native language, there's too much ambiguity here - i.e. you can of course replay a flight or use the autopilot or an external FDM, so that you don't need to explicitly change any XML/Nasal files - i.e. you can do these things purely via the property tree, and thus, telnet.

However, I think there is still a language barrier here - i.e. the whole relationship between properties, the tree and XML seems to be kinda distorted currently ?

Anyway, I really hope that you at least try to help improve the documentation (if in doubt, write it in Italian) - however, just to be clear about it, I am not going to respond too well to the kind of allegations you've been making in response to the answers I have previously posted here - believe it or not, I am in fairly good position to answer most of your questions (once I can parse/understand them), and that also seems to apply to others around here - otherwise, Curt, Thorsten etc would have corrected me already - so what I said was definitely correct, and I was also specifically responding to your questions, I am sorry that my answers apparently didn't make any sense to you, but that's really not my fault - I cannot write in your native language, and I also don't know anything about your professional background, so it would be a little far-fetched to expect me to come up with all sorts of layman analogies just to make a point.

To be perfectly honest, I still have to be convinced that going into so much detail here is worth the hassle, i.e. the pain/gain ratio in these kinds of exchanges (and those initiated by you particularly) doesn't seem to be all that promising, which isn't to say that I don't agree with the conclusion that our docs need some TLC, but I was in fact not just trying to help, but actually responding to the questions you posed.
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 11119
Joined: Tue Mar 25, 2008 8:40 am

Re: Why not use Erlang instead of NASAL?

Postby curt » Tue Oct 11, 2016 7:55 pm

I'm not trying to be negative here, but the way you fly a plane from an airport is to use the provide interfaces (i.e. clicking on cockpit objects, using the joystick, keyboard, mouse, menu's, etc.)

Aircraft are assembled and configured using xml. Aircraft are not flown with xml. Optionally, some aircraft can model more complex systems and animations with nasal. Nasal is used to model complex behavior or relationships without needing to modify core C++ code. Aircraft typically aren't flown with Nasal.

*If* you wish to create an airplane without using xml, then you will need to write some sort of loader for some other format that contains the same type of information and structure.

*If* you wish to remove all the nasal from an existing aircraft, then good luck, you are probably on your own with that.

*If* you wish to write a script that automates a flight of an airplane, then most likely you don't care how the airplane is put together (using xml, 3d models, textures, and nasal) and most likely you just want to manipulate the control values in the property tree at the right time and monitor the state of the system through the property tree.

*If* your needs are relatively simple and you don't need high bandwidth communication, then you can probably do all the property system monitoring and manipulation through the telnet interface with any external program or script language that is capable of basic network communication.

*If* you want embedded scripting with hooks inside flightgear, and you don't want nasal, then you are probably on your own with that. When we discussed this previously we decided that we didn't want to encourage multiple optional script engines because of the chances people will create aircraft with dependencies that no one else has and also the extra complexity of maintaining multiple script engines in the core code.

*If* you really want Erlang and *if* you actually have some experience with it beyond googling the O'Reilly book cover, then you are probably in an extreme minority here. I suspect that within the flight sim community, Erlang is even more obscure than nasal. Favoring erlang over nasal on the basis of nasal obscurity doesn't parse for me. I suspect you will be really on your own to create a personal version of FlightGear with erlang embedded. I haven't seen anyone else speak up here that they are excited to discuss erlang specifics. Did I miss it? I have zero erlang experience myself, but it's my understanding that there is a scripted version and a compiled version available (?)

*If* you want to know my opinion, I like python a lot and I am pushing that direction in my own projects, but FlightGear has too much inertia already with C++, xml, and nasal. These are also good engineering solutions. From a practical standpoint, we just aren't going to change that. But no one would deny you the opportunity to integrate erlang yourself in your own personal version of FlightGear. This is one of the big reasons FlightGear is open-source ... exactly so people can do experiments like this. If it works out really well, maybe you can sell others on the idea and who knows where it goes from there.
Aerospace Engineering and Mechanics
University of Minnesota
curt
Administrator
 
Posts: 1106
Joined: Thu Jan 01, 1970 12:00 am
Location: Minneapolis, MN

Re: Why not use Erlang instead of NASAL?

Postby bugman » Tue Oct 11, 2016 8:34 pm

Firstly, that was not one simple question - so below is not a simple answer ;)

abassign wrote in Tue Oct 11, 2016 7:17 pm:I want to fly a plane from an airport without using the XML and neither NASAL. But only using the commands allowed by the Telnet TCP / UDP connection! If this is possible then it is possible, simply, interface any language, including the incredible Erlang.


I'm not sure about the telnet option, but XML and nasal is not essential (if you have a replacement, for which there is none). My Python experiments are essentially this. As for Erlang, you need to compile this - i.e. there is no more scripting.

Right now I am not interested efficiency, I want to know how it actually works and how the code is layered.


To understand the code without looking at it, see these API docs: http://api-docs.freeflightsim.org/flightgear/index.html

If unable to ... then it is also a problem for the other languages, it means that he FGFS within the code, there are programs that are not based only on the tree of the properties.


You need a bit more. You need listeners, timers, etc. Hooray pointed you to the nasal documentation where these are described - you would need to write replacements for them.

I hope now that everything is clearer, who takes up the challenge, maybe someone has already done it ... who knows ?


This is not clear. Are you talking about documentation, using something other than nasal, properties? Who knows ;)

In exchange, if it were possible, I promise that I make a special documentation on the current Wiki, which I hope tomorrow can become a technical wiki for those who want to challenge themselves in the development of the code.


One problem with code documentation is that it is a shifting target. API documentation is good, but a coder will find reading the source code directly more efficient.

Regards,
Edward
bugman
Moderator
 
Posts: 1524
Joined: Thu Mar 19, 2015 9:01 am
Version: next

Re: Why not use Erlang instead of NASAL?

Postby Hooray » Tue Oct 11, 2016 8:39 pm

I am remotely familiar with Erlang, and I am familiar with FlightGear, Nasal and Python and to some extent with Lua.
Erlang is not suitable for inclusion into fgfs in the FGNasalSys/FGPythonSys fashion (and it'd be overkill, too) for reasons fairly obvious to anyone familiar with the techonlogy stacks (and fgfs restrictions/requirements) involved.

However, if someone wanted to remote control fgfs from erlang that should be dead easy using one of the networking options - and in fact, with Erlang it would even be straightforward to use the netfdm (or any other binary protocol) without causing too much headache, that's one of the strengths of Erlang (i.e. binary pattern matching to be exact)

Apart frrom that, it is true that "Nasal" may be obscure as a name - but again, it's really heavily based on concepts borrowed from ECMAScript, it will look, and feel, familiar with anyone familiar with C-based language, including JavaScript/Java - and that also applies to the programming paradigms supported by Nasal.

Like I said previously, supporting Erlang exclusively for aircraft scripting would put an end to that, at least for people who don't have a professional background in software development or who hold PhDs related fields, or have some other strong functional background (LISP/Scheme).

To be honest, I find the whole debate highly academic - someone familiar with these technology stacks could protoype a working integration via the telnet/props protocol within 30 minutes - or even using web sockets.

Erlang's main strengths simply cannot be leveraged when it comes to the legacy codebase that FlightGear is, and it doesn't seem like the OP is even just remotely familiar with the key ingredients for a working integration - despite the fact, that you don't need more than hooking up an Erlang telnet client to the props daemon in fgfs (which Curt actually wrote originally).

Again, this could be an interesting technical discussion for a number of reasons, but as usual, it's just abstract thinking jumping from one idea to another while skipping all the interesting parts, making the whole thing hugely frustrating for anyone interested in the technical details.

An Erlang client connecting to flightgea via telnet could be implemented in under 30 minutes, really - and it would be a good starting point for people to explore why we have given certain responses here.
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 11119
Joined: Tue Mar 25, 2008 8:40 am

Re: Why not use Erlang instead of NASAL?

Postby Hooray » Tue Oct 11, 2016 8:47 pm

then it is also a problem for the other languages, it means that he FGFS within the code, there are programs that are not based only on the tree of the properties.


yeah, this is one of the key insights, even though you are drawing the conclusion for the wrong reasons, the conclusion is correct - this is generally referred to as the property tree being the sole IPC mechanism, which it simply isn't in many parts - otherwise, multi-threading (and distributed setups, but also saving/loading flights and resetting the sim would be much easier to implement)

The docs I posted carefully explain the high level concepts and you simply need to take it from there, like Curt previously hinted at: we cannot possibly explain each keyword/technology - what I posted is correct and sufficient to look up the bits missing, just like you don't learn how to operate an airplane by someone pointing out to you what a yoke is - there is more to it, and if you are lacking the corresponding background, it will all sound like gibberish to you, because there is too much information encrypted using hundredds of acronyms, abbreviations and keywords that make no sense to you, and that you need to look up over and over again - at that point, you are basically suffering from a "stack overflow".

I can kinda relate to that actually, I am not the slightest bit interested in 3D modeling or FDMs - and it would literally take me months to get up to scratch with all the terminology, skills etc - but I am aware of that, so that I don't even try to waste my time doing those things.

You seem to be juggling tons of ideas and concepts that only make sense to you from a high level standpoint, so that everything falls apart once someone goes into detail to explain how these things actually work.

But to be honest, for someone like you, the wiki contains tons of excellent, and accessible, information - but maybe that "stack overflow" in combination with the language barrier is simply too much to handle so that the whole things becomes unnecessarily frustrating for all parties involved ?
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 11119
Joined: Tue Mar 25, 2008 8:40 am

Re: Why not use Erlang instead of NASAL?

Postby kamikaze » Wed Mar 08, 2017 2:55 pm

+1 for Python
kamikaze
 
Posts: 7
Joined: Wed Mar 08, 2017 2:44 pm

Re: Why not use Erlang instead of NASAL?

Postby geed » Sat Mar 11, 2017 4:01 pm

I want to answer to the OP's first post.

Nasal has been designed with usability in mind. Andy took useful and sane features of JavaScript, Python and Perl and combined them in Nasal. The language syntax is quite close to ECMAScript of Brendan Eich which is today better known as JavaScript and used by millions of coders around the world, just think of the scope design, functionscope over block scope. Stuff that one needs too learn and that will be a mighty weapon in software development if understood and placed well.

Due to its Javascript like design it is way more usable for a majority of developers than if we would choose Erlang. Compared to JavaScript or ECMAScript, Erlangs user base is really small.

Nasal is designed with usability and flexibility in mind. Erlang is designed as a really small set of language parts, almost microscopic ;) and it is quite hard to get your head around the language as a beginner. Although, if understood well, this language can give you great freedom in writing concurrent processes and systems. This is why it's used mostly for backend software or services.

By the way, and that might be very important for an implementation into a performance hungry simulation, Erlang feature and is based around running sub processes that, if they fail, will fail and be deleted and restarted. In a Simulation you will want to be able to control your data flow and how much is been copied from point to point and when. Timing is important for performance. If you can't control the state of an integrated part of that process, it might be difficult to guarantee good rendering times. Script execution needs to be deterministic.

@abassign, How far did you get in analyzing Erlang? Please try to implement a real world application or solve a real world problem with it and I would like to know how you evaluate the language or the environment afterwards. This is not meant as a joke or to mock you, please Test Erlang and come back and present the problem you solved with the solution you came up with. I would be extremely interested in your approach and what analysis you made and how you relate that to a possible implementation as a scripting language in Flightgear.

The key lies in a better documentation with more examples. Nasal is not difficult to understand and maybe we need to find the time to document the different cases of using Nasal somewhere.
geed
 
Posts: 75
Joined: Fri Apr 18, 2014 12:53 pm
Location: in between
Callsign: G-EED
Version: 2017.3.1
OS: OSX, Win8.1

Re: Why not use Erlang instead of NASAL?

Postby Hooray » Sat Mar 11, 2017 5:39 pm

Agreed on all counts - the thing to keep in mind is that the primary restrictions related to Nasal are mainly due to the way it is integrated in FlightGear, and that Erlang (or even Python) would buy us nothing, as long as those restrictions are not addressed - compared to Python, Erlang would be a bad choice actually (I have actually used it every once in a while and tinkered with some of its more esoteric features, so I am a little familiar with it).
The way Erlang works, would however "rock" for anything involving asynchronous FlightGear subsystems along the lines of bugman's FGPythonSys experiments/goals, which is also overlapping with some of the DIS/HLA and RTI/SimKit work that Mathias and Stuart have been tinkering with.

Speaking in general, supporting Erlang instead of Nasal would be an extremely bad move and demonstrate poor decision making for all the reasons previously mentioned here and elsewhere.

Supporting Python (properly) could potentially be a huge killer application/technology enabler, but that would come with its own challenges sooner than later - either way, addressing FlightGear's architectural issues that are limiting scripting/Nasal in FlightGear would also help clean up other subsystems that are unnecessarily sequential by nature and that may unnecessarily clutter the main/rendering loop.
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 11119
Joined: Tue Mar 25, 2008 8:40 am

PreviousNext

Return to Nasal

Who is online

Users browsing this forum: No registered users and 2 guests