Jump to content

bsvingen

Members
  • Posts

    280
  • Joined

  • Last visited

Everything posted by bsvingen

  1. I haven't asked that specifiq question. I think NI knows exactly what they are doing. Their licencing policy works well in a streamlined corporate world whre LV is used for DAQ and/or for development of DAQ-related software for customers, preferably together with NI Hardware. My error was to believe that LV could be used for more general software development. Technically it can, and it has some advantages with respect to speed of development/coding especially if it can be structured as some kind of toolkit utilizing the LV IDE as much as possible. But the licencing makes it a very rare software development tool that very few people actually understand and knows how to use other than setting up the "usual" logging system. My plan for further development/maintainance was to hand it over to someone at the university or previous employer, but this does not seem to happen anytime soon. There simply is no one that knows the technical part and LV enough to do it. They also have to be interested in doing it. Now I am stuck with it, and I wouldn't mind than if it wasn't for the fact that it will cost me money, but even if it didn't I would still have a problem sooner or later. Using LV for this was a mistake. That is really all there is to it. Java would be a better solution in the long run. This is not all that different from all the Matlab code that never leaves the cheap university licenses.
  2. Thanks for the replies, I can clarify below. 1. No, the license and ownership is devided between users, me and the original company. As I said, this is highly specialized software, and not something to sell in the ordinary sense of the word. Although it can be generalized for a much broader audience, this will be a different license/product altogether. 2. Again, this was a cooperation, but yes, the LV license (a very small part of the total recources) that I used belonged to the other company. 3. Correct, although I have access to a PC with LV on it, it is impractical because I need it on my laptop to be able to work when I have time, for instance on weekends and evenings, and at any place I chose. It is inconvinient to the point of uselessness not to have LV on my own laptop to say the truth. 4. Yes and no. At least I would like them to give me a resonable offer of some sort, an answer at least, some communication. To maintain and develop further is not a fulltime job, maybe only 5-10 % or something depending on how much developement. Most of it is actually teaching new persons to use it. But, I do need a license to do this properly, there has to be some continuity, or I start to forget stuff. Anyway, I feel one mistake was made, and that was using LV. Any other software development tools and none of these problems would have emerged, that is the important point here. The initial costs or time or whatever, are really totally uninteresting. Here and now, the license policy at NI does not fit the (my) current situation at all. You can say this is mostly due to inconvinience, but not being able to have LV on my laptop is in fact inconvinient to the point where I rather will go for Java, because then I will never ever again end up in this inconvinience again. And yes, I will simply not pay a full LV license fee for something I do, practically speaking, in my spare time. I could get some of the users to purchase a license for me, but I think this is wrong also, at least I will not do this before NI gives me a reasonable offer.
  3. I just want to air my frustration, and perhaps give a little warning to others. I have made software in Labview. It is very specialized, far from mainstream, thus only a hanfull of users. It is somewhat general in purpose right now, but with more than enough future measurement functionality to use LV. Problem is, I am working for someone else now than I used to, and I cannot use the lisenses for LV (6 to 2009) that I used to. The software itself is very much alive, after I have convinced several key personel to purchase LV licenses (Full development system is needed for proper use of the software, it is more like a toolkit), but no one else but me has the combined competence in the technical and LV things to develop it further, or even maintain it. Bottom line is, for future developement I have to purchase lisenses myself as a privat person. Although I can afford it, there are other issues involved. What about previous versions of LV? Some are still using older versions, how do I obtain licenses for these? I am personally responsible for NI selling a dozen or so full development systems to use my software (all are site lecenses, so I don't know exactly how many). I don't like being a sales person for NI, and having to pay for it, at least not from my own wallet. There have been some discussions here about LV being a real programming language. I agree on the technical parts of this, but sooner or later license problems and version problems will pop up, and these problems are brick walls with no way through or around or over. So, LV being a real programming language - not by a long shot. If you believe this, as I did, you will end up in unsolvable problems sooner or later. I have contacted NI about my little frustration, and so far I have heard nothing. This tells me that they just don't care somehow. The only viable option right now is to use something else, and preferably Java. Luckily most of the core parts are already in C++ through C DLL wrappers, so the transition won't be all torture, but still. What I have learned from this is: If it can be made in LV, this does not mean it should be made in LV. If it can be made with something else, this does indeed mean that it should. And - use LV exclusively for what it was ment to be used for , namely DAQ. </rant> - as they say
  4. 1,005 downloads

    Author: bsvingen - Bjornar Svingen --see readme file for contact information Description: A set of VIs that creates and controls pointer-data pairs. The basic idea is to simulate random access memory and malloc()/free() by using one single LV2 style global. The data type must specified in "..\Pointer\Data Typedef\Data Typedef__P.vi", or it can be replaced with an LVOOP class for LV 8.2. The only restriction to the number of references is the physical memory on the computer. The global stores data in an Array and uses a separate Bool Array to control access and free/protect the data. The "address" to the data is returned directly with no type conversion (int32). Basicly the LV2 global takes data as input, put the data in an array within the global and returns the index where the data is set. This index therefore becomes a pointer to the data, and can be used later to set and get data. The upper 8 bits of the pointer is used as a counter that is incremented by one for each new "dispose pointer" call. The "Get" and "Set" function checks these 8 bits in the pointer with corresponding counter array and throws an error if they are not equal. By doing this an error is thrown when trying to use a disposed pointer. Thanks to JFM for the counter code. Due to the inherent effectiveness of LV2 style globals and no type conversions, this method is twice as efficient as using queue primitives, see examples provided. Functions such as New, Get, Set etc can be found in the ..\Pointer folder. A project file is also provided for LV 8.x. A more general system that takes arbitrary types is called General Reference System and can be found on this Code repository. In contrast to queues that can be regarded as synchronous references to data, this reference system is fully asynchronous. Allocation and freeing of data is done dynamically. Allthough this pointer system may at first glance have some resemblence to "classic" GOOP, it is by no means a GOOP system. This pointer system is best regarded as a normal LV2 global, but with the difference that it returns a pointer (index) to the data, and therefore can be used for an arbitrary number of data. All the VIs in the library are documented. Version History: 1.1.2 Fixed "dispose pointer" and "obtain pointer from pointer". Some other small fixes. 1.1.1 Updated the counter so it will increment at each "dispose pointer" instead of "obtain pointer". 1.1.0 Updated the pointers so that the upper 8 bits is uses as a counter. Using a disposed pointer will therefore create an error. Thanks to JFM. Updated the allocation routine so 100 elements are added in one chunk. Thanks to JFM. 1.0.1 Updated this readme.txt file Fixed a bug in "Obtain P from P" function in the global. Added a placeholder VI (for easier conversion to LV7) 1.0.0: Initial release of the code.
  5. Name: Pointer System Submitter: LAVA 1.0 Content Submitted: 03 Jul 2009 Category: LabVIEW OOP LabVIEW Version: 7.1 Version: 1.1.2 License Type: Creative Commons Attribution 3.0 Potentially make this available on the VI Package Network?: Undecided Author: bsvingen - Bjornar Svingen --see readme file for contact information Description: A set of VIs that creates and controls pointer-data pairs. The basic idea is to simulate random access memory and malloc()/free() by using one single LV2 style global. The data type must specified in "..\Pointer\Data Typedef\Data Typedef__P.vi", or it can be replaced with an LVOOP class for LV 8.2. The only restriction to the number of references is the physical memory on the computer. The global stores data in an Array and uses a separate Bool Array to control access and free/protect the data. The "address" to the data is returned directly with no type conversion (int32). Basicly the LV2 global takes data as input, put the data in an array within the global and returns the index where the data is set. This index therefore becomes a pointer to the data, and can be used later to set and get data. The upper 8 bits of the pointer is used as a counter that is incremented by one for each new "dispose pointer" call. The "Get" and "Set" function checks these 8 bits in the pointer with corresponding counter array and throws an error if they are not equal. By doing this an error is thrown when trying to use a disposed pointer. Thanks to JFM for the counter code. Due to the inherent effectiveness of LV2 style globals and no type conversions, this method is twice as efficient as using queue primitives, see examples provided. Functions such as New, Get, Set etc can be found in the ..\Pointer folder. A project file is also provided for LV 8.x. A more general system that takes arbitrary types is called General Reference System and can be found on this Code repository. In contrast to queues that can be regarded as synchronous references to data, this reference system is fully asynchronous. Allocation and freeing of data is done dynamically. Allthough this pointer system may at first glance have some resemblence to "classic" GOOP, it is by no means a GOOP system. This pointer system is best regarded as a normal LV2 global, but with the difference that it returns a pointer (index) to the data, and therefore can be used for an arbitrary number of data. All the VIs in the library are documented. Version History: 1.1.2 Fixed "dispose pointer" and "obtain pointer from pointer". Some other small fixes. 1.1.1 Updated the counter so it will increment at each "dispose pointer" instead of "obtain pointer". 1.1.0 Updated the pointers so that the upper 8 bits is uses as a counter. Using a disposed pointer will therefore create an error. Thanks to JFM. Updated the allocation routine so 100 elements are added in one chunk. Thanks to JFM. 1.0.1 Updated this readme.txt file Fixed a bug in "Obtain P from P" function in the global. Added a placeholder VI (for easier conversion to LV7) 1.0.0: Initial release of the code. Click here to download this file
  6. 909 downloads

    Author: bsvingen - Bjornar Svingen --see readme file for contact information Description: An LVOOP class that creates and controls reference-data pairs. The basic idea is to simulate random access memory and malloc()/free() by using one single LV2 style global. The data can be of any type (including any LVOOP class and strict typedefs) and can be allocated in any order. The only restriction to the number of references is the physical memory on the computer. The global stores data in a Variant Array and uses a separate Bool Array to control access and free/protect the data. The "address" to the data that is stored in the reference (LV Object) ,is the index in the Variant Array where the data is stored in the LV2 Global. By using Variant as the type, it is possible to get a reference to all types, and there is no need to manually change a typedef and possibly the names for every vi when more than one typedef will be used. A small performance penalty is introduced due to the type conversions to/from Variant. However, due to the inherent effectiveness of LV2 style globals, this method is still 2-3 times faster than an equivalent scheme made with wrappers around queue primitives, but slightly slower than using queue primitives directly, (no wrappers around the queues, see example provided). For an even faster reference system, twice the speed of queue primitives, se the separate "Pointer System" on this Code Repository. In contrast to queues that can be regarded as synchronous references to data, this reference system is fully asynchronous. Allocation and freeing of data is done dynamically. Allthough this reference system may at first glance have some resemblence to "classic" GOOP, it is by no means a GOOP system. The main purpose of the reference system is to have a fully asynchronous and fully reusable system for read and write access to one single instance of data in more than one place. All the VIs in the library are documented. Version History: 1.0.3 Added an example using queue primitives as references with no wrappers. Updated this Readme.txt 1.0.2 Minor fixes to the New function and some text. 1.0.1 Added this readme.txt file + some small cosmetic changes 1.0.0: Initial release of the code.
  7. Name: General reference system Submitter: LAVA 1.0 Content Submitted: 03 Jul 2009 Category: LabVIEW OOP LabVIEW Version: 8.2 Version: 1.0.3 License Type: Creative Commons Attribution 3.0 Potentially make this available on the VI Package Network?: Undecided Author: bsvingen - Bjornar Svingen --see readme file for contact information Description: An LVOOP class that creates and controls reference-data pairs. The basic idea is to simulate random access memory and malloc()/free() by using one single LV2 style global. The data can be of any type (including any LVOOP class and strict typedefs) and can be allocated in any order. The only restriction to the number of references is the physical memory on the computer. The global stores data in a Variant Array and uses a separate Bool Array to control access and free/protect the data. The "address" to the data that is stored in the reference (LV Object) ,is the index in the Variant Array where the data is stored in the LV2 Global. By using Variant as the type, it is possible to get a reference to all types, and there is no need to manually change a typedef and possibly the names for every vi when more than one typedef will be used. A small performance penalty is introduced due to the type conversions to/from Variant. However, due to the inherent effectiveness of LV2 style globals, this method is still 2-3 times faster than an equivalent scheme made with wrappers around queue primitives, but slightly slower than using queue primitives directly, (no wrappers around the queues, see example provided). For an even faster reference system, twice the speed of queue primitives, se the separate "Pointer System" on this Code Repository. In contrast to queues that can be regarded as synchronous references to data, this reference system is fully asynchronous. Allocation and freeing of data is done dynamically. Allthough this reference system may at first glance have some resemblence to "classic" GOOP, it is by no means a GOOP system. The main purpose of the reference system is to have a fully asynchronous and fully reusable system for read and write access to one single instance of data in more than one place. All the VIs in the library are documented. Version History: 1.0.3 Added an example using queue primitives as references with no wrappers. Updated this Readme.txt 1.0.2 Minor fixes to the New function and some text. 1.0.1 Added this readme.txt file + some small cosmetic changes 1.0.0: Initial release of the code. Click here to download this file
  8. QUOTE (Aristos Queue @ Apr 13 2009, 02:40 AM) Yes it does.
  9. QUOTE You are missing the point (at least half of it). The behavior is not the issue, the quality is. More presisely you want to get rid of all possibilities for unexpected things to happen, at least as much as you can. It is about failure modes, not validation of operational modes. Testing of a system and documenting (defining) its subsystem are two different things. Testing a system consisting of undocumented sub systems will still leave you with an experimental system. This is a simple fact. Something tells me some of you just don't get it (no offence ) Without stretching the similarity too far, minimizing failure modes is somewhat similar to minimizing the possibility of bugs entering the code. In this respect LV already is way beyond most other compilers. It is also somewhat similar to the reasons for encapsulation (and OOP). You simply cannot expect the unexpected, but you can minimize the possibility of unexpected things to happen by assuring everything is well defined, minimizing side effects and by reusing things you know have no failure modes. Is it possible to be (reasonably) sure that things are well defined without documenting it so other people can look at it, or at least leave the source open? I doubt it.
  10. QUOTE You have to understand that a mechanical device and a digital device doing the same basic function usually have very different failure modes. It is not a question of wether software is inherently unreliably per default, it is the number of failure modes that is added when going for a digital solution, and the character of those failure modes. An example is ignition system for an engine. A mechanical system consists of lots of moving parts and works untill somthing burns or brakes or gets worn. The failure modes are complete failure on all or some cylinders, or drop in perfomance. Two systems running in parallel will increase MTTF by several orders of magnitude, because all the failure modes in one system is covered by a functional second system. It can run also when both systems fail, if the failure or on different cylinders or general poor performance. A digital system is per default much more reliable because there are no moving parts, there is nothing to break. So, it is easy to assume that one digital system is much more reliable than a parallel mechanical system, because all the failure modes of the mechanical system are removed in the digital system. So, if two digital systems are mounted in parallel, it should be failsafe. This is obviosly not correct. As a start a digital system needs electrical power and the redundancy is transferred to the power distribution. Further, your system must handle all the failure modes in the power distribution (total and intermittent loss of power, power spikes etc). The main important issue is the timing (the basic functionality of the ignition system). In a mechanical system this is handled by cams and contact points. They can brake, become worn out, but nothing more can happen. In a digital system, they need to be programmed, and this one of the main reasons you want a digital system, you can program the timing so it is optimal under all conditions (increasing HP and lower fuel consumption). But this is also where you can add an infinite number of failure modes. A new and dangerous failure mode is too advanced timing for one or several cylinders (ignition happends too early) due for instance to a power spike upsetting the controller. This can completely ruin the engine within a matter of minutes. But the real issue is that a parallel system will not prevent this, it will only make it worse (if ignition already has happened, you cannot "unignite"). Normal redundancy will double the probability of this failure mode. This is a general characteristic of digital control systems, normal redundancy does not work because you have added failure modes that cannot be solved by redundancy. In fact you would be better of with just one controller and focus on reliable power distribution. In flight control systems this is solved by using at least 3 controllers, and using the output of the two most similar. So, the need for triple (and more) redundancy in digital systems is due to the nature of the failure modes, nothing else, and certainly not because it is assumed that software developers include undocumented and experimental trash in finished products. I mean, companies and governments are using billions of billions of dollars to make things as save and reliable as possible. There is no way anyone can convince me that including undocumented and experimental code that potentially can lower this reliability, is ethical.
  11. QUOTE (Ton @ Apr 9 2009, 07:37 AM) All public transportation is soaked in certification systems, but private transportation is a whole different matter. My picture is the airplane I am building for myself. It is a two seat RV-4, fully aerobatic and will be registered as EXPERIMENTAL In contrast to ordinary private aircrafts I am free to put any instrumentation in it I choose, also fully experimental unit, and I will most probably go with just a single unit of this and an extra GPS. The first 40 hours of flight I have to fly alone testing it; recording speed, climb rate etc etc, something I don't want to do manually Maybe a netbook of some kind running LV and hooked on to the Voyager through USB or CAN. But with the paste I am building it will take some years...
  12. QUOTE (Val Brown @ Apr 9 2009, 06:00 AM) I am not sure what you are referring to, insulated? The flight control systems are considered IP by the companies involved, and are pretty much closed in that respect, but a certified aircraft has abselutely no experimental features on board, everything has to be certified by international and local regulations. Certification is a lengthy process and is mostly about documenting every little aspect of every litlle bit.
  13. QUOTE I have never claimed that, you are reading too much into it. What I said was that the same quality and reliability is expected of the software as is expected of every other critical component or subsystem, and that modern systems are increasingly becoming more and more all digital (no old fashioned mechamical operational mode exists). Then, this leads to my main point that including half-finished code in the finished product is not the way to assure the quality and reliability needed for mission critical tasks. There are way to many things that can go wrong as it is, you simply do not add more. In the same way that you would not expect critical mechanical components to fail, you would not expect critical software to fail. Then it is the job for the engineers to do everything they can to prevent critical components/software to fail. This means, among other things, to remove unessesary failure modes. The Airbus is all digital, and the same is B-777 (you should read that article about ADA). What this mean is that there is no other way to control the airplane without going through at least one computer. The Airbus A-320 actually has 5 parallel lines, 5 times redundancy, but it is still all digital, there is no manual/mechanical mode except possibly manual elevator trim. QUOTE you are confusing undocumented features with experimental features Maybe, I am afterall a confusing person But there is a third alternative; undocumented and experimental :ninja:
  14. QUOTE (Justin Goeres @ Apr 6 2009, 04:08 PM) This is not true at all. Modern digital controllers control whole systems in a way that is impossible in a "fail safe" mode. There are no fail safe mode, either it works or it doesn't. The actuators themselves cannot be operated without proper digital signals, except in service/testing mode. Whole system are designed to be controlled digitally, and there is no other way to control them. There are two main reasons for this. One reason is that statistics show that computerized control is more fail safe than any other alternative (mechanical or electric). The other reason is that digital control enables the processes to run much more efficient because they are pushed far beyond what previously would be called a safe, or even operational state. Take for instance the fuel injection in any ordinary modern car (common rail TDI). If the controller shuts down, the engine stops in the same manner as if the crank broke, but this is an unproblematic event (for anyone except the driver ). A much bigger problem occurs if the controller does something wrong, like too much fuel, uneven fuel distribution, too much boost etc due to a software error. This would be the same as if the crank suddenly would change the relative angles of the pistons (not that it is possible, but it would produce similar problems). All larger modern ships are controlled "by wire" with very sophisticated, almost AI-like navigational and maneuvering systems using GPS, radar, ultrasonic sensors, inertia sensors etc, most of them don't even have steering wheels, and those that do have it for show. A software error due to some hidden and undocumented experimental feature for the reason of "testing" something new, is completely out of the question. Airbus air liners use fly by wire, and has done so for decades already. It uses a system with several computers working in parallel, and there is no manual or mechanical backup whatsoever. The point is, computerized control is as much a part of a system as the crank shaft is a part of an engine. The same reliability and quality is expected of the software in those controllers as is expected of the alloy content in the pistons, or the structural integrity of the ship's hull, or the main beams of the wings. Undocumented and unreleaved features in the software is as expected and assumed as you would expect to have part of the ship being secretely made of some unknown experimental paper foil because one of the engineers had a "bright" idea.
  15. QUOTE (Justin Goeres @ Apr 6 2009, 04:21 AM) The point is: You wouldn't use Google Chrome and a $500 laptop as a controller for the space shuttle even though it can be done It all depends on what you are doing. If you are simply "writing software", nobody cares about documentation of the compiler as long as the software works as intended. If you work as a consultant in engineering, you have no liability what so ever for the results you produce, and can use whatever software you choose. But if you produce and sell controllers for power plants, biochemical factories, car engines etc, you can be held responsible, at least in part if the controller faults due to any error (software or hardware). If it turns out that the error happened because of unrevealed/undocumented features, and you knew that the compiler had tons of them without saying anything, you are most likely in deep sh*t. Another point is that now we know that NI is shipping software with lots of undocumented and unrevealed features consisting of random snippets of code from arbitrary software engineers, most likely with little or no experience in any real life industry at all. In fact, it is so much of it that it would be too expensive to either remove it or document it. I understand that this practice allows a faster development paste, but this is purely a pragmatic reasoning. I mean, open source software allways has a "stable" branch that is fully "documented" (open) and does not contain experimental code. Any changes done there is to fix bugs. The experimental code is reserved for "nightly builds" and betas, but at least it is documented. What NI is doing is to include the experimental code in the stable branch with no documentation what so ever because the source is closed. I would prefer the open source way. IMO that is much better ethics.
  16. Working with pointers in LV through DLLs can be a bit very confusing IMO. LV does not know how memory is allocated in the DLL, so it has no idea what to return when memory is allocated/deallocated. There are special memory functions in external.h, but I have never used them myself. The way I do it is to have certain rules that I know will work, for me at least. Never return a dynamic value (array and similar with unknown size) in the return argument. Only return basic types like integers (could be pointer) or floats or nothing at all. Allways allocate memory in LV when returning arrays and similar within the function body. When you have lots of complex data types (arrays, clusters, objects) in the DLL, leave them there and return a pointer to LV. Preferably a pointer to a class. Use LV to call the methods via the pointer and return/send data only when needed through well defined get/set methods where all array sizes are defined in LV. In your special case, I think what is wrong is that LV does not know the size of the return string, it doesn't know the size of anything really. You have to refactor so that both the return string and b have memory allocated in LV before the call, and this includes a wrapper that returns void or int or something.
  17. QUOTE Actually this is the essence of the ethics. A similar situation would be a turbojet engine with an undocumented/unrevealed feature that boosted output by 50% - at the expense of greatly increasing the probability of cathastrophic failure (this feature could be implemented in software within one of the engine controllers). If the feature is there, then it should be documented, othervise it should be removed. Let say I used LV to program the embedded controller, then everything about that controller must be documented, and using software that I know include tons of undocumented/unrevealed features is simply not an option. Often making sure that the unexpected does not happen, is much more important than simply making it work as expected. In most industries this is the rule, not the exception.
  18. I see a confusion of ethics and reasons here. You can find reasons for everything, and good reasons does not need to be ethically correct. LV is used for many things, some of these things include controlling expensive, dangerous or even vital hardware. In those cases, if you don't have the source code available, the only ethical correct thing to do is to use documented features only. On the other hand, if that software does include undocumented and unrevealed (untested) features, how can users be sure that those features cannot be invoked accidentally? So, The only ethical correct thing to do is to document everything, also unrevealed and untested features. All undocumented features should be removed.
  19. QUOTE (crelf @ Mar 31 2009, 11:01 PM) Here you are, select color and size : http://www.shivaoutdoors.com/shout/product...me=Ganja%20Topi
  20. Just for the record. I think LV is one of the best things that has happened to PCs But that doesn't stop me from wondering about certain things.
  21. I remember when I worked with a computer hardware engineer designing measurement equipment for the oil industry. He needed to hire software engineers to help program the embedded systems we used (simple stuff according to him). He found it impossible, because all engineers freshly out of universities had tons of knowledge about Windows and how to make GUIs using OO and inheretence, and I bet they could do it very efficiently, but not a single one had any idea how to program simple embedded chips. This was 12 years ago. QUOTE I fail to see how spending time making my code utilize multiple cores or machines efficiently would do anything but kill coding efficiency. Especially when the code can be coded within minutes in C/C++ and run at highest execution speed possible. Over-generalizations and complex solutions is very seldom a good substitute for proper knowledge of how to solve simple problems.
  22. Having both "Applying UML and Patterns" by Larman and "Design Patterns" by Gamma et al or the GoF, it seems to me that Larmans book is really what I want. I have only browsed through them, but Larmans book goes into detail of the process of OO analysis and design, while the GoF assume that you already know all that and is more of a reference to typical patterns that have shown to be workin well.
  23. QUOTE How about a random access queue?
  24. Purchased both p-p-p-pattern books at the local university book store They better be good.
  25. This is exactly what labview is made for. There exist an arbitrary wave vi somewhere. Just put one revolution (the total signal for one revolution) into the wave pattern, and the vi will do the rest (frequency, amplitude etc).
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.