]> Softwares of Agnibho - medscript-lite.git/commitdiff
JS Port of MedScript
authorAgnibho Mondal <mondal@agnibho.com>
Thu, 2 Nov 2023 04:34:11 +0000 (10:04 +0530)
committerAgnibho Mondal <mondal@agnibho.com>
Thu, 2 Nov 2023 04:34:11 +0000 (10:04 +0530)
19 files changed:
COPYING [new file with mode: 0644]
README [new file with mode: 0644]
README.md [deleted file]
package-lock.json
package.json
public/favicon.ico
public/index.html
public/template/default.html [new file with mode: 0644]
public/template/medcert.html [new file with mode: 0644]
src/App.vue
src/assets/logo.png [deleted file]
src/assets/logo.svg [new file with mode: 0644]
src/components/EditScreen.vue [new file with mode: 0644]
src/components/HelloWorld.vue [deleted file]
src/components/HomeScreen.vue [new file with mode: 0644]
src/components/PrescriberScreen.vue [new file with mode: 0644]
src/components/RenderScreen.vue [new file with mode: 0644]
src/main.js
vue.config.js

diff --git a/COPYING b/COPYING
new file mode 100644 (file)
index 0000000..f288702
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<https://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<https://www.gnu.org/licenses/why-not-lgpl.html>.
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..2498486
--- /dev/null
+++ b/README
@@ -0,0 +1,214 @@
+MedScript Lite
+==============
+
+MedScript Lite is a medical prescription writing software. It is primarily for
+medical practitioners for writing prescriptions.
+
+MedScript Lite is the JavaScript implementation of MedScript. It has a limited
+feature set. But it can run on any device with a modern web browser.
+
+The purpose of the program is to enable medical practitioners to prepare
+computerized prescriptions. The program has been designed after the commonly
+used prescription format among the medical practitioners in India.
+Inclusion of prescription style of other regions will hopefully be implemented
+in future updates.
+
+File
+----
+
+The program uses a custom file format mpaz (Medical Prescription Archive -
+Zipped). It is a zip file in a specific format which includes:
+
+1. A meta.json file containing file type and mpaz version.
+2. A prescription.zip file containing the actual prescription.
+3. An attachment folder containing attached files.
+4. A template folder containing the bundled prescription template. This
+feature is not supported in MedScript Lite.
+
+Optionally the mpaz archive may also include an S/MIME signature and
+certificate for authentication, but it is not implemented in MedScript Lite.
+
+The structure of the mpaz file is as follows:
+
+    <filename>.mpaz (zipped file)
+    |-- meta.json (e.g. {"type": "MedScript", "version": "<mpaz version>"})
+    |-- prescription.json (Prescription object in JSON format)
+    |-- template (included template for rendering)
+    |   |-- index.html (Jinja2 template)
+    |   |-- <other template files e.g. CSS>
+    |-- attachment (directory containing attachments)
+    |   |-- <attached files>
+    |-- signature (optional: S/MIME signature)
+    |-- certificate.pem (optional: full certificate chain including end-user, intermediates and root certificate)
+
+Install
+-------
+
+To use MedScript Lite, you can git repository and build the app from source.
+The following commands can be run in a GNU/Linux terminal.
+
+1. Clone the git repository.
+
+    git clone https://code.agnibho.com/repo/medscript-lite.git
+
+2. Enter the cloned directory.
+
+    cd medscript-lite
+
+3. Run the app.
+
+    npm run serve
+
+This will create a local web server and serve the app from there. It can be accessed
+at localhost:8080 from any modern web browser in the local system.
+
+4. Build the app (optional).
+
+    npm run build
+
+This will create a "dist" directory containing the compiled app. This
+directory maybe placed in a server for online use.
+
+Usage
+-----
+
+MedScript Lite has a very intuitive interface.
+
+The home screen contains the options to open a file, create a new file,
+editing prescriber information and the information about the app.
+
+### Creating a prescription
+
+A new prescription can be created by clicking on the "New" button. The
+prescription editing screen will open. The required data can be entered in the
+form.
+
+The parts of a prescription are as follows:
+1. ID
+2. Name
+3. Age
+4. Sex
+5. Address
+6. Contact
+7. Diagnosis
+8. Extra (any extra data about the patient. can also be used to certify)
+9. DAW (dispense as written)
+10. Mode (consultation mode e.g. tele-consultation)
+11. Note (clinical notes)
+12. Report (available reports)
+13. Advice
+14. Investigation
+15. Medication
+16. Additional
+17. Attachment (files can be attached with the prescription from this option)
+
+After editing the "Save" button below can be used to save the data in a
+mpaz file and download it. The "Render" button will render the prescription
+into a printable format. The "Cancel" button can be used to cancel the edits
+and return to the home screen.
+
+### Opening a prescription
+
+The home screen has the option of opening a prescription. A prescription can
+be opened by selecting the file in the home screen and clicking the "Open"
+button.
+
+### Rendering a prescription
+
+The prescriptions can be rendered and subsequently printed. To render a
+prescription, click on the "Render" button in the edit screen. The rendered
+prescription can be printed or converted to PDF by using the print to pdf
+option in the browser.
+
+### Template
+
+The program uses nunjucks (similar to Jinja2) template for rendering the
+prescription. Two templates (one for default prescription and one for medical
+certificates) are included with the app. Custom templates are not supported.
+
+Note that MedScript Lite do not include the templates in the mpaz file.
+
+### Medical Certificate
+
+The Certify/Extra area can be used to write a medical prescription. Select the
+medical certificate template from the edit screen for proper rendering.
+
+Prescriber
+----------
+
+The data of the practitioner is stored locally in the browser. To view or edit
+the prescriber information, click the "Prescriber" button in the home screen.
+
+The following information can be entered about the prescriber:
+
+1. Name
+2. Qualification
+3. Registration
+4. Address
+5. Contact
+6. Extra
+
+Prescription Object
+-------------------
+
+The program uses a Prescription object to store the prescription data. The
+structure of the Prescription object is as follows:
+
+    prescription (Prescription object)
+    |-- date (string: date-time in the %Y-%m-%d %H:%M:%S format)
+    |-- id (string: the id of the prescription)
+    |-- name (string: the name of the patient)
+    |-- age (string: the age of the patient, may contain unit)
+    |-- sex (string: sex of the patient)
+    |-- address (string: address of the patient)
+    |-- contact (string: contact number / email of the patient)
+    |-- extra (string: extra data related to the prescription, may also be used for writing certificates)
+    |-- mode (string: the mode of consultation e.g. tele-consultation)
+    |-- daw (boolean: dispense as written)
+    |-- diagnosis (string: diagnosis of the patient's condition)
+    |-- note (string: clinical note e.g. history, physical examination)
+    |-- report (string: available reports)
+    |-- advice (string: advice given to the patient, not the medications)
+    |-- investigation (string: investigations suggested for the patient)
+    |-- medication (string: the list of medications prescribed)
+    |-- additional (string: any additional advice/instructions)
+    |-- prescriber (Prescriber object)
+    |   |-- name (string: the name of the prescriber)
+    |   |-- qualification (string: the qualification of the prescriber)
+    |   |-- registration (string: the registration number of the prescriber)
+    |   |-- address (string: the address of the prescriber)
+    |   |-- contact (string: contact number / email of the prescriber)
+    |   |-- extra (string: any extra data about the prescriber)
+
+Website
+-------
+
+<https://code.agnibho.com/medscript-lite/>
+
+License
+-------
+
+MedScript Lite
+
+Copyright (C) 2023 Dr. Agnibho Mondal
+
+MedScript Lite is free software: you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the Free Software
+Foundation, either version 3 of the License, or (at your option) any later
+version.
+
+MedScript Lite is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+MedScript Lite. If not, see <https://www.gnu.org/licenses/>.
+
+Contact
+-------
+
+Dr. Agnibho Mondal
+
+mondal@agnibho.com
+
+www.agnibho.com
diff --git a/README.md b/README.md
deleted file mode 100644 (file)
index 9e0298c..0000000
--- a/README.md
+++ /dev/null
@@ -1,24 +0,0 @@
-# medscript-lite
-
-## Project setup
-```
-npm install
-```
-
-### Compiles and hot-reloads for development
-```
-npm run serve
-```
-
-### Compiles and minifies for production
-```
-npm run build
-```
-
-### Lints and fixes files
-```
-npm run lint
-```
-
-### Customize configuration
-See [Configuration Reference](https://cli.vuejs.org/config/).
index c2d477eb3effd6884ff004a233119f37e8227407..607092027df2e194537f1c8bda0cd9c4596fd9c9 100644 (file)
@@ -8,7 +8,12 @@
       "name": "medscript-lite",
       "version": "0.1.0",
       "dependencies": {
+        "@popperjs/core": "^2.11.8",
+        "bootstrap": "^5.3.2",
         "core-js": "^3.8.3",
+        "jszip": "^3.10.1",
+        "nunjucks": "^3.2.4",
+        "nunjucks-date-filter": "^0.1.1",
         "vue": "^3.2.13"
       },
       "devDependencies": {
@@ -16,7 +21,7 @@
         "@babel/eslint-parser": "^7.12.16",
         "@vue/cli-plugin-babel": "~5.0.0",
         "@vue/cli-plugin-eslint": "~5.0.0",
-        "@vue/cli-service": "~5.0.0",
+        "@vue/cli-service": "^5.0.8",
         "eslint": "^7.32.0",
         "eslint-plugin-vue": "^8.0.3"
       }
       "integrity": "sha512-C16M+IYz0rgRhWZdCmK+h58JMv8vijAA61gmz2rspCSwKwzBebpdcsiUmwrtJRdphuY30i6BSLEOP8ppbNLyLg==",
       "dev": true
     },
+    "node_modules/@popperjs/core": {
+      "version": "2.11.8",
+      "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
+      "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/popperjs"
+      }
+    },
     "node_modules/@sideway/address": {
       "version": "4.1.4",
       "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.4.tgz",
       "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
       "dev": true
     },
+    "node_modules/a-sync-waterfall": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/a-sync-waterfall/-/a-sync-waterfall-1.0.1.tgz",
+      "integrity": "sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA=="
+    },
     "node_modules/accepts": {
       "version": "1.3.8",
       "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
       "version": "3.1.3",
       "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
       "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
-      "dev": true,
+      "devOptional": true,
       "dependencies": {
         "normalize-path": "^3.0.0",
         "picomatch": "^2.0.4"
         "node": ">=8"
       }
     },
+    "node_modules/asap": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+      "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA=="
+    },
     "node_modules/astral-regex": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz",
       "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==",
-      "dev": true,
+      "devOptional": true,
       "engines": {
         "node": ">=8"
       }
       "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
       "dev": true
     },
+    "node_modules/bootstrap": {
+      "version": "5.3.2",
+      "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.2.tgz",
+      "integrity": "sha512-D32nmNWiQHo94BKHLmOrdjlL05q1c8oxbtBphQFb9Z5to6eGRDCm0QgeaZ4zFBHzfg2++rqa2JkqCcxDy0sH0g==",
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/twbs"
+        },
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/bootstrap"
+        }
+      ],
+      "peerDependencies": {
+        "@popperjs/core": "^2.11.8"
+      }
+    },
     "node_modules/brace-expansion": {
       "version": "1.1.11",
       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
       "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
-      "dev": true,
+      "devOptional": true,
       "dependencies": {
         "fill-range": "^7.0.1"
       },
       "version": "3.5.3",
       "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
       "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
-      "dev": true,
+      "devOptional": true,
       "funding": [
         {
           "type": "individual",
       "version": "5.1.2",
       "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
       "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
-      "dev": true,
+      "devOptional": true,
       "dependencies": {
         "is-glob": "^4.0.1"
       },
       "dev": true
     },
     "node_modules/commander": {
-      "version": "8.3.0",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
-      "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
-      "dev": true,
-      "engines": {
-        "node": ">= 12"
-      }
+      "version": "2.20.3",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+      "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+      "dev": true
     },
     "node_modules/commondir": {
       "version": "1.0.1",
     "node_modules/core-util-is": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
-      "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
-      "dev": true
+      "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
     },
     "node_modules/cosmiconfig": {
       "version": "7.1.0",
       "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.2.tgz",
       "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ=="
     },
+    "node_modules/de-indent": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz",
+      "integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==",
+      "dev": true,
+      "optional": true,
+      "peer": true
+    },
     "node_modules/debug": {
       "version": "4.3.4",
       "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
       "version": "7.0.1",
       "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
       "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
-      "dev": true,
+      "devOptional": true,
       "dependencies": {
         "to-regex-range": "^5.0.1"
       },
         "node": ">=12"
       }
     },
+    "node_modules/html-minifier-terser/node_modules/commander": {
+      "version": "8.3.0",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz",
+      "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==",
+      "dev": true,
+      "engines": {
+        "node": ">= 12"
+      }
+    },
     "node_modules/html-tags": {
       "version": "3.3.1",
       "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz",
         "node": ">= 4"
       }
     },
+    "node_modules/immediate": {
+      "version": "3.0.6",
+      "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
+      "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="
+    },
     "node_modules/import-fresh": {
       "version": "3.3.0",
       "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
     "node_modules/inherits": {
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
-      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
-      "dev": true
+      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
     },
     "node_modules/ipaddr.js": {
       "version": "2.1.0",
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
       "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
-      "dev": true,
+      "devOptional": true,
       "dependencies": {
         "binary-extensions": "^2.0.0"
       },
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
       "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
-      "dev": true,
+      "devOptional": true,
       "engines": {
         "node": ">=0.10.0"
       }
       "version": "4.0.3",
       "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
       "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
-      "dev": true,
+      "devOptional": true,
       "dependencies": {
         "is-extglob": "^2.1.1"
       },
       "version": "7.0.0",
       "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
       "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
-      "dev": true,
+      "devOptional": true,
       "engines": {
         "node": ">=0.12.0"
       }
     "node_modules/isarray": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-      "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
-      "dev": true
+      "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
     },
     "node_modules/isexe": {
       "version": "2.0.0",
         "graceful-fs": "^4.1.6"
       }
     },
+    "node_modules/jszip": {
+      "version": "3.10.1",
+      "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz",
+      "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==",
+      "dependencies": {
+        "lie": "~3.3.0",
+        "pako": "~1.0.2",
+        "readable-stream": "~2.3.6",
+        "setimmediate": "^1.0.5"
+      }
+    },
+    "node_modules/jszip/node_modules/readable-stream": {
+      "version": "2.3.8",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+      "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+      "dependencies": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.3",
+        "isarray": "~1.0.0",
+        "process-nextick-args": "~2.0.0",
+        "safe-buffer": "~5.1.1",
+        "string_decoder": "~1.1.1",
+        "util-deprecate": "~1.0.1"
+      }
+    },
+    "node_modules/jszip/node_modules/safe-buffer": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+    },
+    "node_modules/jszip/node_modules/string_decoder": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+      "dependencies": {
+        "safe-buffer": "~5.1.0"
+      }
+    },
     "node_modules/keyv": {
       "version": "4.5.4",
       "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
         "node": ">= 0.8.0"
       }
     },
+    "node_modules/lie": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
+      "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
+      "dependencies": {
+        "immediate": "~3.0.5"
+      }
+    },
     "node_modules/lilconfig": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.1.0.tgz",
       "integrity": "sha512-23g5BFj4zdQL/b6tor7Ji+QY4pEfNH784BMslY9Qb0UnJWRAt+lQGLYmRaM0KDBwIG23ffEBELhZDP2rhi9f/Q==",
       "dev": true
     },
+    "node_modules/moment": {
+      "version": "2.29.4",
+      "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz",
+      "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==",
+      "engines": {
+        "node": "*"
+      }
+    },
     "node_modules/mrmime": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.1.tgz",
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
       "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
-      "dev": true,
+      "devOptional": true,
       "engines": {
         "node": ">=0.10.0"
       }
         "url": "https://github.com/fb55/nth-check?sponsor=1"
       }
     },
+    "node_modules/nunjucks": {
+      "version": "3.2.4",
+      "resolved": "https://registry.npmjs.org/nunjucks/-/nunjucks-3.2.4.tgz",
+      "integrity": "sha512-26XRV6BhkgK0VOxfbU5cQI+ICFUtMLixv1noZn1tGU38kQH5A5nmmbk/O45xdyBhD1esk47nKrY0mvQpZIhRjQ==",
+      "dependencies": {
+        "a-sync-waterfall": "^1.0.0",
+        "asap": "^2.0.3",
+        "commander": "^5.1.0"
+      },
+      "bin": {
+        "nunjucks-precompile": "bin/precompile"
+      },
+      "engines": {
+        "node": ">= 6.9.0"
+      },
+      "peerDependencies": {
+        "chokidar": "^3.3.0"
+      },
+      "peerDependenciesMeta": {
+        "chokidar": {
+          "optional": true
+        }
+      }
+    },
+    "node_modules/nunjucks-date-filter": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/nunjucks-date-filter/-/nunjucks-date-filter-0.1.1.tgz",
+      "integrity": "sha512-xKIMGB+UH1mRnk1/ofAVpU+6Fm52KQWfkCCjMWYohuBTj/Id/qy8zIVuE5lpwtavPyHz96sW2dCawNdPPhn0SQ==",
+      "dependencies": {
+        "moment": "^2.9.0"
+      }
+    },
+    "node_modules/nunjucks/node_modules/commander": {
+      "version": "5.1.0",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz",
+      "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==",
+      "engines": {
+        "node": ">= 6"
+      }
+    },
     "node_modules/object-assign": {
       "version": "4.1.1",
       "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
         "node": ">=6"
       }
     },
+    "node_modules/pako": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
+      "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
+    },
     "node_modules/param-case": {
       "version": "3.0.4",
       "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz",
       "version": "2.3.1",
       "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
       "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
-      "dev": true,
+      "devOptional": true,
       "engines": {
         "node": ">=8.6"
       },
     "node_modules/process-nextick-args": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
-      "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
-      "dev": true
+      "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
     },
     "node_modules/progress": {
       "version": "2.0.3",
       "version": "3.6.0",
       "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
       "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
-      "dev": true,
+      "devOptional": true,
       "dependencies": {
         "picomatch": "^2.2.1"
       },
         "node": ">= 0.4"
       }
     },
+    "node_modules/setimmediate": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+      "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA=="
+    },
     "node_modules/setprototypeof": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
         "url": "https://opencollective.com/webpack"
       }
     },
-    "node_modules/terser/node_modules/commander": {
-      "version": "2.20.3",
-      "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
-      "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
-      "dev": true
-    },
     "node_modules/text-table": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
       "version": "5.0.1",
       "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
       "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
-      "dev": true,
+      "devOptional": true,
       "dependencies": {
         "is-number": "^7.0.0"
       },
     "node_modules/util-deprecate": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
-      "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
-      "dev": true
+      "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
     },
     "node_modules/utila": {
       "version": "0.4.0",
       "integrity": "sha512-fUs4B4L+mlt8/XAtSOGMUO1TXmAelItBPtJG7CyHJfYTdDjwisntGO2JQz7oUsatOY9o68+57eziUVNw/mRHmA==",
       "dev": true
     },
+    "node_modules/vue-template-compiler": {
+      "version": "2.7.15",
+      "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.7.15.tgz",
+      "integrity": "sha512-yQxjxMptBL7UAog00O8sANud99C6wJF+7kgbcwqkvA38vCGF7HWE66w0ZFnS/kX5gSoJr/PQ4/oS3Ne2pW37Og==",
+      "dev": true,
+      "optional": true,
+      "peer": true,
+      "dependencies": {
+        "de-indent": "^1.0.2",
+        "he": "^1.2.0"
+      }
+    },
     "node_modules/vue-template-es2015-compiler": {
       "version": "1.9.1",
       "resolved": "https://registry.npmjs.org/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz",
index fc89f35b0978eb55ba6eeb59f2efc41b62f75370..293d79484e39bf39ed70ee6c727d3169d7e89c54 100644 (file)
@@ -8,7 +8,12 @@
     "lint": "vue-cli-service lint"
   },
   "dependencies": {
+    "@popperjs/core": "^2.11.8",
+    "bootstrap": "^5.3.2",
     "core-js": "^3.8.3",
+    "jszip": "^3.10.1",
+    "nunjucks": "^3.2.4",
+    "nunjucks-date-filter": "^0.1.1",
     "vue": "^3.2.13"
   },
   "devDependencies": {
@@ -16,7 +21,7 @@
     "@babel/eslint-parser": "^7.12.16",
     "@vue/cli-plugin-babel": "~5.0.0",
     "@vue/cli-plugin-eslint": "~5.0.0",
-    "@vue/cli-service": "~5.0.0",
+    "@vue/cli-service": "^5.0.8",
     "eslint": "^7.32.0",
     "eslint-plugin-vue": "^8.0.3"
   },
index df36fcfb72584e00488330b560ebcf34a41c64c2..845ec91186d2d9d12c85441af80ef372d867c9a5 100644 (file)
Binary files a/public/favicon.ico and b/public/favicon.ico differ
index 3e5a13962197105f2078d2a224cc57dfa09b4893..64282974ea5bebc42e6992a7f734852a033efcdd 100644 (file)
@@ -1,3 +1,12 @@
+<!--
+MedScript Lite
+Copyright (C) 2023 Dr. Agnibho Mondal
+This file is part of MedScript Lite.
+MedScript Lite is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+MedScript Lite is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+You should have received a copy of the GNU General Public License along with MedScript Lite. If not, see <https://www.gnu.org/licenses/>.
+-->
+
 <!DOCTYPE html>
 <html lang="">
   <head>
diff --git a/public/template/default.html b/public/template/default.html
new file mode 100644 (file)
index 0000000..dc86644
--- /dev/null
@@ -0,0 +1,104 @@
+<!--
+MedScript Lite
+Copyright (C) 2023 Dr. Agnibho Mondal
+This file is part of MedScript Lite.
+MedScript Lite is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+MedScript Lite is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+You should have received a copy of the GNU General Public License along with MedScript Lite. If not, see <https://www.gnu.org/licenses/>.
+-->
+
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Prescription</title>
+    <!--link rel="stylesheet" href="style.css"-->
+    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
+  </head>
+  <body>
+    <div>
+      <div class="header" style="position:fixed;top:0;width:95%;left:50%;transform:translateX(-50%);background:white;top:0;border-bottom:2px solid black;height:200px">
+        <table class="table">
+          <tr>
+            <td class="col-sm-8">
+              <h1>{{prescriber.name}}</h1>
+              <h2>{{prescriber.qualification}}</h2>
+              <h3>{{prescriber.registration}}</h3>
+            </td>
+            <td class="col-sm-4">
+              <pre>{{prescriber.address}}</pre>
+              <p>{% if prescriber.contact %}Contact: {{prescriber.contact}}{% endif %}</p>
+              <pre>{{prescriber.extra}}</pre>
+            </td>
+          </tr>
+        </table>
+      </div>
+      <div class="content">
+        <table class="table">
+          <thead><tr><td><div class="header-space" style="height: 200px;"></div></td></tr></thead>
+          <tbody>
+            <tr>
+              <td>
+                <table class="table">
+                  <tr>
+                    <td class="text-end" colspan="3"><small>{% if id %}ID: {{id}}{% endif %}</small></td>
+                  </tr>
+                  <tr>
+                    <td><p><strong>Name:</strong> {{name}}</p></td>
+                    <td><p><strong>Age:</strong> {{age}}</p></td>
+                    <td><p><strong>Sex:</strong> {{sex}}</p></td>
+                  </tr>
+                  <tr>
+                    <td colspan="3"><small>{% if address %}Address: {{address}}{% endif %} {% if contact %}Contact: {{contact}}{% endif %}</small></td>
+                  </tr>
+                  <tr>
+                    <td colspan="3"><small>{% if extra %}{{extra}}{% endif %}</small></td>
+                  </tr>
+                </table>
+                <table class="table">
+                  <tr>
+                    <td class="col-sm-4 text-center"><p><strong>Clinical Notes</strong></p></td>
+                    <td class="col-sm-8 text-center"><p><strong>Advice</strong></p></td>
+                  </tr>
+                  <tr>
+                    <td style="border-right: 2px solid gray">
+                      {% if diagnosis %}
+                      {% if diagnosis_list|length > 1 %}
+                      <ul>
+                        {% for diag in diagnosis_list %}<li><strong>{{diag}}</strong></li>{% endfor %}
+                      </ul>
+                      {% else %}
+                      <p><strong>{{diagnosis}}</strong></p>
+                      {% endif %}
+                      {% endif %}
+                      {% if note %}<pre>{{note}}</pre>{% endif %}
+                      {% if report %}<pre>{{report}}</pre>{% endif %}
+                    </td>
+                    <td style="border-left: 2px solid gray">
+                      {% if advice %}<pre>{{advice}}</pre>{% endif %}
+                      <ol>
+                        {% for med in medication_list %}
+                        <li><strong>{{med[0]}}</strong><br>
+                          <small><em>{{med[1]}}</em></small></li>
+                        <hr>
+                        {% endfor %}
+                      </ol>
+                      {% if investigation %}<pre>{{investigation}}</pre>{% endif %}
+                      {% if additional %}<pre>{{additional}}</pre>{% endif %}
+                    </td>
+                  </tr>
+                </table>
+              </td>
+            </tr>
+          </tbody>
+          <tfoot><tr><td><div class="footer-space" style="height: 100px;"></div></td></tr></tfoot>
+        </table>
+      </div>
+      <div class="footer" style="position:fixed;bottom:0;width:95%;left:50%; transform:translateX(-50%);background:white;bottom:0;border-top:2px solid black;height:100px">
+        <table class="table">
+          <tr><td class="col-sm-8">{% if mode %}Consultation: {{mode}}{% endif %}<br>{% if daw %}Dispense as written{% endif %}</td><td class="col-sm-4"><br><br></td></tr>
+          <tr><td><p>{{date|date("YYYY-MM-DDTHH:mm:ss")}}</p></td><td class="text-center" style="border-top: 2px solid gray"><p>Signature</p></td></tr>
+        </table>
+      </div>
+    </div>
+  </body>
+</html>
diff --git a/public/template/medcert.html b/public/template/medcert.html
new file mode 100644 (file)
index 0000000..c81e76e
--- /dev/null
@@ -0,0 +1,76 @@
+<!--
+MedScript Lite
+Copyright (C) 2023 Dr. Agnibho Mondal
+This file is part of MedScript Lite.
+MedScript Lite is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+MedScript Lite is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+You should have received a copy of the GNU General Public License along with MedScript Lite. If not, see <https://www.gnu.org/licenses/>.
+-->
+
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Prescription</title>
+    <!--link rel="stylesheet" href="style.css"-->
+    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
+  </head>
+  <body>
+    <div>
+      <div class="header" style="position:fixed;top:0;width:95%;left:50%;transform:translateX(-50%);background:white;top:0;border-bottom:2px solid black;height:200px">
+        <table class="table">
+          <tr>
+            <td class="col-sm-8">
+              <h1>{{prescriber.name}}</h1>
+              <h2>{{prescriber.qualification}}</h2>
+              <h3>{{prescriber.registration}}</h3>
+            </td>
+            <td class="col-sm-4">
+              <pre>{{prescriber.address}}</pre>
+              <p>{% if prescriber.contact %}Contact: {{prescriber.contact}}{% endif %}</p>
+              <pre class="formatted">{{prescriber.extra}}</pre>
+            </td>
+          </tr>
+        </table>
+      </div>
+      <div class="content">
+        <table class="table">
+          <thead><tr><td><div class="header-space" style="height: 200px;"></div></td></tr></thead>
+          <tbody>
+            <tr>
+              <td>
+                <table class="table">
+                  <tr>
+                    <td class="text-end" colspan="3"><small>{% if id %}ID: {{id}}{% endif %}</small></td>
+                  </tr>
+                  <tr>
+                    <td><p><strong>Name:</strong> {{name}}</p></td>
+                    <td><p><strong>Age:</strong> {{age}}</p></td>
+                    <td><p><strong>Sex:</strong> {{sex}}</p></td>
+                  </tr>
+                  <tr>
+                    <td colspan="3"><small>{% if address %}Address: {{address}}{% endif %} {% if contact %}Contact: {{contact}}{% endif %}</small></td>
+                  </tr>
+                </table>
+                <table class="table">
+                  <tr>
+                    <td>{% if diagnosis %}<strong>Provisional Diagnosis: {{diagnosis}}</strong>{% endif %}</td>
+                  </tr>
+                  <tr>
+                    <td><pre class="text-justify">{{extra}}</p></td>
+                  </tr>
+                </table>
+              </td>
+            </tr>
+          </tbody>
+          <tfoot><tr><td><div class="footer-space" style="height: 100px;"></div></td></tr></tfoot>
+        </table>
+      </div>
+      <div class="footer" style="position:fixed;bottom:0;width:95%;left:50%; transform:translateX(-50%);background:white;bottom:0;border-top:2px solid black;height:100px">
+        <table class="table">
+          <tr><td class="col-sm-8">{% if mode %}Consultation: {{mode}}{% endif %}<br>{% if daw %}Dispense as written{% endif %}</td><td class="col-sm-4"><br><br></td></tr>
+          <tr><td><p>{{date|date("YYYY-MM-DDTHH:mm:ss")}}</p></td><td class="text-center" style="border-top: 2px solid gray"><p>Signature</p></td></tr>
+        </table>
+      </div>
+    </div>
+  </body>
+</html>
index 591a0312d9dac2a6f0e766b2a8f9151d62decd94..d0fe856bb7e7121a8b5699941713acd937e02d77 100644 (file)
+<!--
+MedScript Lite
+Copyright (C) 2023 Dr. Agnibho Mondal
+This file is part of MedScript Lite.
+MedScript Lite is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+MedScript Lite is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+You should have received a copy of the GNU General Public License along with MedScript Lite. If not, see <https://www.gnu.org/licenses/>.
+-->
+
 <template>
-  <img alt="Vue logo" src="./assets/logo.png">
-  <HelloWorld msg="Welcome to Your Vue.js App"/>
+       <div id="app">
+               <div class="container-fluid">
+                       <div v-show="!showComponent.render">
+                               <div class="alert alert-primary text-center">
+                                       <h1>MedScript Lite</h1>
+                               </div>
+                               <hr>
+                       </div>
+                       <home-screen @openPrescription="loadPrescription" @openAttachment="loadAttachment" @newFile="newFile" @editPrescriber="editPrescriber" v-show="showComponent.home"></home-screen><br>
+                       <edit-screen @renderPrescription="renderPrescription" @cancel="cancelEdit" :openedPrescription="openedPrescription" :openedAttachment="openedAttachment" v-show="showComponent.edit"></edit-screen>
+                       <render-screen :prescription="prescription" :template="template" @closeRender="closeRender" v-show="showComponent.render"></render-screen>
+                       <prescriber-screen @cancel="cancelPrescriber" v-show="showComponent.prescriber"></prescriber-screen>
+                       <div v-show="!showComponent.render">
+                               <hr>
+                       </div>
+               </div>
+       </div>
 </template>
 
 <script>
-import HelloWorld from './components/HelloWorld.vue'
+       import "bootstrap/dist/css/bootstrap.min.css"
+       import "bootstrap"
+       import HomeScreen from "./components/HomeScreen.vue"
+       import EditScreen from "./components/EditScreen.vue"
+       import RenderScreen from "./components/RenderScreen.vue"
+       import PrescriberScreen from "./components/PrescriberScreen.vue"
 
-export default {
-  name: 'App',
-  components: {
-    HelloWorld
-  }
-}
+       export default {
+               name: "MedScript Lite",
+               data() {
+                       return {
+                               openedPrescription: {
+                                       date: "",
+                                       id: "",
+                                       name: "",
+                                       age: "",
+                                       sex: "",
+                                       address: "",
+                                       contact: "",
+                                       diagnosis: "",
+                                       extra: "",
+                                       daw: "",
+                                       mode: "",
+                                       note: "",
+                                       report: "",
+                                       advice: "",
+                                       investigation: "",
+                                       medication: "",
+                                       additional: "",
+                                       attachment: ""
+                               },
+                               openedAttachment: [],
+                               prescription: null,
+                               template: null,
+                               showComponent: {home: true, edit: false, render: false, prescriber: false}
+                       }
+               },
+               methods: {
+                       loadPrescription(data) {
+                               this.openedPrescription=data;
+                               this.showComponent.home=false;
+                               this.showComponent.edit=true;
+                       },
+                       loadAttachment(data) {
+                               this.openedAttachment=data;
+                       },
+                       renderPrescription(prescription, template) {
+                               this.prescription=structuredClone(prescription);
+                               this.template=structuredClone(template);
+                               this.showComponent.edit=false;
+                               this.showComponent.render=true;
+                       },
+                       closeRender() {
+                               console.log("close")
+                               this.showComponent.render=false;
+                               this.showComponent.edit=true;
+                       },
+                       cancelEdit() {
+                               this.showComponent.edit=false;
+                               this.showComponent.home=true;
+                       },
+                       editPrescriber() {
+                               this.showComponent.home=false;
+                               this.showComponent.prescriber=true;
+                       },
+                       cancelPrescriber() {
+                               this.showComponent.prescriber=false;
+                               this.showComponent.home=true;
+                       },
+                       newFile() {
+                               this.openedPrescription=null;
+                               this.showComponent.home=false;
+                               this.showComponent.edit=true;
+                       },
+               },
+               components: {
+                       HomeScreen,
+                       EditScreen,
+                       RenderScreen,
+                       PrescriberScreen
+               }
+       }
 </script>
-
-<style>
-#app {
-  font-family: Avenir, Helvetica, Arial, sans-serif;
-  -webkit-font-smoothing: antialiased;
-  -moz-osx-font-smoothing: grayscale;
-  text-align: center;
-  color: #2c3e50;
-  margin-top: 60px;
-}
-</style>
diff --git a/src/assets/logo.png b/src/assets/logo.png
deleted file mode 100644 (file)
index f3d2503..0000000
Binary files a/src/assets/logo.png and /dev/null differ
diff --git a/src/assets/logo.svg b/src/assets/logo.svg
new file mode 100644 (file)
index 0000000..2f3ef6d
--- /dev/null
@@ -0,0 +1,95 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   width="256mm"
+   height="256mm"
+   viewBox="0 0 256 256"
+   version="1.1"
+   id="svg1"
+   inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
+   sodipodi:docname="medscript.svg"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:svg="http://www.w3.org/2000/svg">
+  <sodipodi:namedview
+     id="namedview1"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:showpageshadow="2"
+     inkscape:pageopacity="0.0"
+     inkscape:pagecheckerboard="0"
+     inkscape:deskcolor="#d1d1d1"
+     inkscape:document-units="mm"
+     inkscape:zoom="0.78484147"
+     inkscape:cx="684.21461"
+     inkscape:cy="556.16327"
+     inkscape:window-width="1920"
+     inkscape:window-height="1057"
+     inkscape:window-x="0"
+     inkscape:window-y="0"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="layer1" />
+  <defs
+     id="defs1">
+    <rect
+       x="64.546011"
+       y="157.62982"
+       width="8.5361009"
+       height="12.195528"
+       id="rect4" />
+    <rect
+       x="65.860126"
+       y="136.58935"
+       width="825.59149"
+       height="709.76193"
+       id="rect3" />
+  </defs>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <rect
+       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.64583333;stroke-dasharray:none"
+       id="rect1"
+       width="246.88208"
+       height="247.04169"
+       x="4.6859736"
+       y="4.2118435" />
+    <rect
+       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.64583333;stroke-dasharray:none"
+       id="rect2"
+       width="246.71169"
+       height="18.73151"
+       x="4.7141724"
+       y="4.4137478" />
+    <text
+       xml:space="preserve"
+       transform="scale(0.26458333)"
+       id="text2"
+       style="fill:none;stroke:black;stroke-opacity:1;stroke-width:1px;stroke-linejoin:miter;stroke-linecap:butt;font-family:sans-serif;font-size:10.66666667px;line-height:125%;letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect3)" />
+    <text
+       xml:space="preserve"
+       transform="matrix(16.933333,0,0,16.933333,-1053.8839,-2662.6264)"
+       id="text3"
+       style="font-size:10.6667px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;white-space:pre;shape-inside:url(#rect4);vector-effect:non-scaling-stroke;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.03125;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"><tspan
+         x="64.546875"
+         y="167.06644"
+         id="tspan2"><tspan
+           style="vector-effect:non-scaling-stroke"
+           id="tspan1">R</tspan></tspan></text>
+    <text
+       xml:space="preserve"
+       style="font-size:180.622px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;vector-effect:non-scaling-stroke;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:0.264583;stroke-linecap:butt;stroke-linejoin:miter;stroke-dasharray:none;stroke-opacity:1;-inkscape-stroke:hairline"
+       x="107.8268"
+       y="235.77658"
+       id="text5"><tspan
+         sodipodi:role="line"
+         id="tspan5"
+         style="font-style:italic;vector-effect:non-scaling-stroke;fill:#000000;fill-opacity:1;stroke-width:0.264583;stroke-dasharray:none;-inkscape-stroke:hairline"
+         x="107.8268"
+         y="235.77658">x</tspan></text>
+  </g>
+</svg>
diff --git a/src/components/EditScreen.vue b/src/components/EditScreen.vue
new file mode 100644 (file)
index 0000000..9770b9b
--- /dev/null
@@ -0,0 +1,291 @@
+<!--
+MedScript Lite
+Copyright (C) 2023 Dr. Agnibho Mondal
+This file is part of MedScript Lite.
+MedScript Lite is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+MedScript Lite is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+You should have received a copy of the GNU General Public License along with MedScript Lite. If not, see <https://www.gnu.org/licenses/>.
+-->
+
+<template>
+       <div id="edit-screen">
+               <form @submit.prevent="saveData">
+                       <div class="form-group row mb-2">
+                               <label for="date" class="col-sm-2">Date:</label>
+                               <div class="col-sm-10">
+                                       <input type="datetime-local" step="any" class="form-control" id="date" v-model="prescription.date">
+                               </div>
+                       </div>
+                       <div class="form-group row mb-2">
+                               <label for="id" class="col-sm-2">ID:</label>
+                               <div class="col-sm-10">
+                                       <input type="text" class="form-control" id="id" v-model="prescription.id">
+                               </div>
+                       </div>
+                       <div class="form-group row mb-2">
+                               <label for="name" class="col-sm-2">Name:</label>
+                               <div class="col-sm-10">
+                                       <input type="text" class="form-control" id="name" v-model="prescription.name">
+                               </div>
+                       </div>
+                       <div class="form-group row mb-2">
+                               <label for="age" class="col-sm-2">Age:</label>
+                               <div class="col-sm-10">
+                                       <input type="text" class="form-control" id="age" v-model="prescription.age">
+                               </div>
+                       </div>
+                       <div class="form-group row mb-2">
+                               <label for="sex" class="col-sm-2">Sex:</label>
+                               <div class="col-sm-10">
+                                       <input type="text" class="form-control" id="sex" v-model="prescription.sex">
+                               </div>
+                       </div>
+                       <div class="form-group row mb-2">
+                               <label for="address" class="col-sm-2">Address:</label>
+                               <div class="col-sm-10">
+                                       <input type="text" class="form-control" id="address" v-model="prescription.address">
+                               </div>
+                       </div>
+                       <div class="form-group row mb-2">
+                               <label for="contact" class="col-sm-2">Contact:</label>
+                               <div class="col-sm-10">
+                                       <input type="text" class="form-control" id="contact" v-model="prescription.contact">
+                               </div>
+                       </div>
+                       <div class="form-group row mb-2">
+                               <label for="diagnosis" class="col-sm-2">Diagnosis:</label>
+                               <div class="col-sm-10">
+                                       <input type="text" class="form-control" id="diagnosis" v-model="prescription.diagnosis">
+                               </div>
+                       </div>
+                       <div class="form-group row mb-2">
+                               <label for="extra" class="col-sm-2">Extra/Certificate:</label>
+                               <div class="col-sm-10">
+                                       <textarea class="form-control" id="extra" v-model="prescription.extra"></textarea>
+                               </div>
+                       </div>
+                       <div class="form-group row mb-2">
+                               <label for="mode" class="col-sm-2">Mode:</label>
+                               <div class="col-sm-10">
+                                       <input type="text" class="form-control" id="mode" v-model="prescription.mode">
+                               </div>
+                       </div>
+                       <div class="form-group row mb-2">
+                               <div class="col-sm-2">DAW:</div>
+                               <div class="col-sm-10">
+                                       <div class="form-check">
+                                               <input type="checkbox" class="form-check-input" id="daw" v-model="prescription.daw">
+                                               <label class="form-check-label" for="daw">Dispense as written</label>
+                                       </div>
+                               </div>
+                       </div>
+                       <hr>
+                       <div class="form-group row">
+                               <label for="note" class="col-sm-2">Clinical Notes:</label>
+                               <div class="col-sm-10">
+                                       <textarea class="form-control" id="note" v-model="prescription.note"></textarea>
+                               </div>
+                       </div>
+                       <hr>
+                       <div class="form-group row">
+                               <label for="report" class="col-sm-2">Reports:</label>
+                               <div class="col-sm-10">
+                                       <textarea class="form-control" id="report" v-model="prescription.report"></textarea>
+                               </div>
+                       </div>
+                       <hr>
+                       <div class="form-group row">
+                               <label for="advice" class="col-sm-2">Advice:</label>
+                               <div class="col-sm-10">
+                                       <textarea class="form-control" id="advice" v-model="prescription.advice"></textarea>
+                               </div>
+                       </div>
+                       <hr>
+                       <div class="form-group row">
+                               <label for="investigation" class="col-sm-2">Investigations:</label>
+                               <div class="col-sm-10">
+                                       <textarea class="form-control" id="investigation" v-model="prescription.investigation"></textarea>
+                               </div>
+                       </div>
+                       <hr>
+                       <div class="form-group row">
+                               <label for="medication" class="col-sm-2">Medications:</label>
+                               <div class="col-sm-10">
+                                       <textarea class="form-control" id="medication" v-model="prescription.medication"></textarea>
+                               </div>
+                       </div>
+                       <hr>
+                       <div class="form-group row">
+                               <label for="additional" class="col-sm-2">Additional:</label>
+                               <div class="col-sm-10">
+                                       <textarea class="form-control" id="additional" v-model="prescription.additional"></textarea>
+                               </div>
+                       </div>
+                       <hr>
+                       <div class="form-group row mb-2">
+                               <label for="attachment" class="col-sm-2">Attachments:</label>
+                               <div class="col-sm-10">
+                                       <ul class="list-group" id="attachment">
+                                               <li class="list-group-item" v-for="(item, index) in attachment" :key="index" @click="selectAttachment(index)" :class="isSelected(index)">
+                                                       {{item.name}}
+                                               </li>
+                                       </ul>
+                               </div>
+                       </div>
+                       <div class="form-group row">
+                               <div class="col-sm-6 offset-sm-2">
+                                       <input type="file" class="form-control" @change="loadAttachment($event)">
+                               </div>
+                               <div class="col-sm-2 d-grid gap-2">
+                                       <button type="button" class="btn btn-secondary" @click="downloadAttachment">Download</button>
+                               </div>
+                               <div class="col-sm-2 d-grid gap-2">
+                                       <button type="button" class="btn btn-secondary" @click="removeAttachment">Remove</button>
+                               </div>
+                       </div>
+                       <hr>
+                       <div class="form-group row mb-2">
+                               <label for="template" class="col-sm-2">Template</label>
+                               <div class="col-sm-10">
+                                       <select class="form-select mb-2" v-model="template">
+                                               <option value=default>Default Template</option>
+                                               <option value="medcert">Medical Certificate</option>
+                                       </select>
+                               </div>
+                       </div>
+                       <div class="form-group row">
+                               <div class="col-sm-3 offset-sm-3 d-grid gap-2">
+                                       <button type="submit" class="btn btn-primary">Save</button>
+                               </div>
+                               <div class="col-sm-3 d-grid gap-2">
+                                       <button type="button" @click="renderPrescription" class="btn btn-success">Render</button>
+                               </div>
+                               <div class="col-sm-3 d-grid gap-2">
+                                       <button type="button" @click="cancel" class="btn btn-warning">Cancel</button>
+                               </div>
+                       </div>
+               </form>
+       </div>
+</template>
+<script>
+       import JSZip from "jszip"
+       export default {
+               props: ["openedPrescription", "openedAttachment"],
+               data() {
+                       return {
+                               prescription: this.newData(),
+                               attachment: [],
+                               selected: 0,
+                               template: "default"
+                       }
+               },
+               methods: {
+                       newData() {
+                               var prescription={
+                                       date: new Date(new Date() - new Date().getTimezoneOffset() * 60000).toISOString().split(".")[0],
+                                       id: "",
+                                       name: "",
+                                       age: "",
+                                       sex: "",
+                                       address: "",
+                                       contact: "",
+                                       diagnosis: "",
+                                       extra: "",
+                                       daw: "",
+                                       mode: "",
+                                       note: "",
+                                       report: "",
+                                       advice: "",
+                                       investigation: "",
+                                       medication: "",
+                                       additional: "",
+                                       attachment: "",
+                                       prescriber: this.loadPrescriber()
+                               };
+                               return prescription;
+                       },
+                       saveData() {
+                               var prescription=JSON.stringify(this.prescription, null, 2);
+                               var filename=""
+                               if(this.prescription.id){
+                                       filename=this.prescription.id.name.replace(/ +/g, "_")
+                               }
+                               else if(this.prescription.name){
+                                       filename=this.prescription.name.replace(/ +/g, "_")
+                               }
+                               else {
+                                       filename="prescription"
+                               }
+                               var zipfile=new JSZip();
+                               zipfile.file("prescription.json", prescription);
+                               zipfile.file("meta.json", JSON.stringify({"type": "MedScript", "version": "0.2"}))
+                               this.attachment.forEach((item) => {
+                                       zipfile.file("attachment/"+item.name, item.content)
+                               });
+                               zipfile.generateAsync({ type: "blob" })
+                                       .then(function (blob) {
+                                               var link=document.createElement("a");
+                                               link.href=URL.createObjectURL(blob);
+                                               link.download=filename+".mpaz";
+                                               link.click();
+                                       });
+                       },
+                       loadPrescriber() {
+                               return JSON.parse(localStorage.getItem("prescriber"))
+                       },
+                       renderPrescription() {
+                               this.$emit("renderPrescription", this.prescription, this.template);
+                       },
+                       cancel() {
+                               this.$emit("cancel");
+                       },
+                       selectAttachment(index) {
+                               this.selected=index
+                       },
+                       isSelected(index) {
+                               if(index==this.selected) {
+                                       return("active");
+                               }
+                               else {
+                                       return("");
+                               }
+                       },
+                       loadAttachment(event){
+                               var filename=event.target.files[0]
+                               var reader=new FileReader();
+                               reader.readAsArrayBuffer(filename);
+                               reader.onload=function(e) {
+                                       this.attachment.push({"name": event.target.files[0]["name"], "content": e.target.result});
+                               }.bind(this)
+                       },
+                       removeAttachment(){
+                               this.attachment.splice(this.selected, 1);
+                               this.selected=0;
+                       },
+                       downloadAttachment(){
+                               try {
+                                       var link=document.createElement("a");
+                                       link.href=URL.createObjectURL(new Blob([this.attachment[this.selected].content]));
+                                       link.download=this.attachment[this.selected].name;
+                                       link.click();
+                               }
+                               catch (e) {
+                                       console.log(e.message)
+                               }
+                       }
+               },
+               watch: {
+                       openedPrescription: function(){
+                               if(this.openedPrescription) {
+                                       this.prescription=structuredClone(this.openedPrescription)
+                               }
+                               else {
+                                       this.prescription=this.newData()
+                               }
+                       },
+                       openedAttachment: function(){
+                               this.attachment=structuredClone(this.openedAttachment)
+                       }
+               }
+       };
+</script>
diff --git a/src/components/HelloWorld.vue b/src/components/HelloWorld.vue
deleted file mode 100644 (file)
index 879051a..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-<template>
-  <div class="hello">
-    <h1>{{ msg }}</h1>
-    <p>
-      For a guide and recipes on how to configure / customize this project,<br>
-      check out the
-      <a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
-    </p>
-    <h3>Installed CLI Plugins</h3>
-    <ul>
-      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
-      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
-    </ul>
-    <h3>Essential Links</h3>
-    <ul>
-      <li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
-      <li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
-      <li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
-      <li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
-      <li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
-    </ul>
-    <h3>Ecosystem</h3>
-    <ul>
-      <li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
-      <li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
-      <li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
-      <li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
-      <li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
-    </ul>
-  </div>
-</template>
-
-<script>
-export default {
-  name: 'HelloWorld',
-  props: {
-    msg: String
-  }
-}
-</script>
-
-<!-- Add "scoped" attribute to limit CSS to this component only -->
-<style scoped>
-h3 {
-  margin: 40px 0 0;
-}
-ul {
-  list-style-type: none;
-  padding: 0;
-}
-li {
-  display: inline-block;
-  margin: 0 10px;
-}
-a {
-  color: #42b983;
-}
-</style>
diff --git a/src/components/HomeScreen.vue b/src/components/HomeScreen.vue
new file mode 100644 (file)
index 0000000..a5141e3
--- /dev/null
@@ -0,0 +1,107 @@
+<!--
+MedScript Lite
+Copyright (C) 2023 Dr. Agnibho Mondal
+This file is part of MedScript Lite.
+MedScript Lite is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+MedScript Lite is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+You should have received a copy of the GNU General Public License along with MedScript Lite. If not, see <https://www.gnu.org/licenses/>.
+-->
+
+<template>
+       <div id="home-screen">
+               <form class="mb-4">
+                       <div class="input-group">
+                               <span class="input-group-text">Select File</span>
+                               <input type="file" accept=".mpaz" class="form-control" v-on:change="loadFile">
+                               <button type="submit" class="btn btn-primary">Open</button>
+                       </div>
+               </form>
+               <div class="row">
+                       <div class="col-sm-4 d-grid gap-2">
+                               <button class="btn btn-success" @click="newFile">New File</button>
+                       </div>
+                       <div class="col-sm-4 d-grid gap-2">
+                               <button class="btn btn-primary" @click="prescriber">Prescriber</button>
+                       </div>
+                       <div class="col-sm-4 d-grid gap-2">
+                               <button class="btn btn-info" @click="about">About</button>
+                       </div>
+               </div>
+               <div v-show="showAbout" class="alert alert-info mt-4">
+                       <p>MedScript Lite version 0.1</p>
+                       <p>MedScript Lite is a JavaScript implementation of MedScript. It has a limited feature set but it can run on any device with a modern web browser.</p>
+                       <p><a href="https://code.agnibho.com/medscript">https://code.agnibho.com/medscript</a></p>
+                       <p>Copyright &copy; 2023{{new Date().getFullYear()>2023 ? "-"+new Date().getFullYear() : ""}} Dr. Agnibho Mondal</p>
+               </div>
+       </div>
+</template>
+
+<script>
+       import JSZip from "jszip"
+
+       export default {
+               data() {
+                       return {
+                               filename: "",
+                               openedPrescription: Object,
+                               openedAttachment: [],
+                               showAbout: false
+                       }
+               },
+               methods: {
+                       loadFile(e) {
+                               var filename=e.target.files[0];
+                               if (filename) {
+                                       var reader=new FileReader();
+                                       reader.readAsArrayBuffer(filename);
+                                       reader.onload=function(e) {
+                                               var zipdata=e.target.result;
+                                               var zip=new JSZip();
+                                               zip.loadAsync(zipdata)
+                                                       .then(function(zip) {
+                                                               this.openedAttachment=[]
+                                                               var entries=Object.entries(zip.files)
+                                                               entries=entries.map((item)=>item[0])
+                                                               var attachName=entries.filter((element)=>element.startsWith("attachment/") && element!="attachment/")
+                                                               if(attachName.length==0) {
+                                                                       this.$emit("openAttachment", this.openedAttachment);
+                                                               }
+                                                               var attachFile=[]
+                                                               attachName.forEach((item)=>attachFile.push(zip.files[item]))
+                                                               attachFile.forEach(function(item, index) {
+                                                                       item.async("arraybuffer")
+                                                                               .then(function(content) {
+                                                                                       this.openedAttachment.push({"name": attachName[index].replace("attachment/", ""), "content": content});
+                                                                                       if(index==attachName.length-1){
+                                                                                               this.$emit("openAttachment", this.openedAttachment);
+                                                                                       }
+                                                                               }.bind(this));
+                                                               }.bind(this));
+                                                               var presfile=zip.files["prescription.json"];
+                                                               presfile.async("string")
+                                                                       .then(function(content) {
+                                                                               this.openedPrescription=JSON.parse(content);
+                                                                               this.$emit("openPrescription", this.openedPrescription);
+                                                                       }.bind(this));
+                                                       }.bind(this));
+                                       }.bind(this)
+                               }
+                       },
+                       newFile() {
+                               this.$emit("newFile")
+                       },
+                       prescriber() {
+                               this.$emit("editPrescriber")
+                       },
+                       about() {
+                               this.showAbout=!this.showAbout
+                       }
+               }
+       }
+</script>
+
+<style>
+#home-screen {
+       text-align: center;
+}
+</style>
diff --git a/src/components/PrescriberScreen.vue b/src/components/PrescriberScreen.vue
new file mode 100644 (file)
index 0000000..b70056c
--- /dev/null
@@ -0,0 +1,81 @@
+<!--
+MedScript Lite
+Copyright (C) 2023 Dr. Agnibho Mondal
+This file is part of MedScript Lite.
+MedScript Lite is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+MedScript Lite is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+You should have received a copy of the GNU General Public License along with MedScript Lite. If not, see <https://www.gnu.org/licenses/>.
+-->
+
+<template>
+       <div id="prescriber-screen">
+               <form @submit.prevent="save">
+                       <div class="form-group row mb-2">
+                               <label for="name" class="col-sm-2">Name:</label>
+                               <div class="col-sm-10">
+                                       <input type="text" class="form-control" id="name" v-model="prescriber.name">
+                               </div>
+                       </div>
+                       <div class="form-group row mb-2">
+                               <label for="registration" class="col-sm-2">Registration:</label>
+                               <div class="col-sm-10">
+                                       <input type="text" class="form-control" id="registration" v-model="prescriber.registration">
+                               </div>
+                       </div>
+                       <div class="form-group row mb-2">
+                               <label for="address" class="col-sm-2">Address:</label>
+                               <div class="col-sm-10">
+                                       <textarea class="form-control" id="address" v-model="prescriber.address"></textarea>
+                               </div>
+                       </div>
+                       <div class="form-group row mb-2">
+                               <label for="contact" class="col-sm-2">Contact:</label>
+                               <div class="col-sm-10">
+                                       <textarea class="form-control" id="contact" v-model="prescriber.contact"></textarea>
+                               </div>
+                       </div>
+                       <div class="form-group row mb-2">
+                               <label for="extra" class="col-sm-2">Extra:</label>
+                               <div class="col-sm-10">
+                                       <textarea class="form-control" id="extra" v-model="prescriber.extra"></textarea>
+                               </div>
+                       </div>
+                       <div class="form-group row">
+                               <div class="col-sm-3 offset-sm-3 d-grid gap-2">
+                                       <button type="submit" class="btn btn-primary">Save</button>
+                               </div>
+                               <div class="col-sm-3 d-grid gap-2">
+                                       <button type="button" @click="cancel" class="btn btn-warning">Cancel</button>
+                               </div>
+                       </div>
+               </form>
+       </div>
+</template>
+
+<script>
+       export default {
+               data() {
+                       return {
+                               prescriber: this.loadPrescriber()
+                       }
+               },
+               methods: {
+                       loadPrescriber() {
+                               var prescriber;
+                               try {
+                                       prescriber=JSON.parse(localStorage.getItem("prescriber"));
+                               }
+                               catch {
+                                       prescriber={name: "", registration: "", address: "", contact: "", extra: ""}
+                               }
+                               return prescriber;
+                       },
+                       save() {
+                               localStorage.setItem("prescriber", JSON.stringify(this.prescriber));
+                       },
+                       cancel() {
+                               this.$emit("cancel");
+                       }
+               }
+       }
+</script>
diff --git a/src/components/RenderScreen.vue b/src/components/RenderScreen.vue
new file mode 100644 (file)
index 0000000..33cc27c
--- /dev/null
@@ -0,0 +1,49 @@
+<!--
+MedScript Lite
+Copyright (C) 2023 Dr. Agnibho Mondal
+This file is part of MedScript Lite.
+MedScript Lite is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+MedScript Lite is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+You should have received a copy of the GNU General Public License along with MedScript Lite. If not, see <https://www.gnu.org/licenses/>.
+-->
+
+<template>
+       <div id="render-screen">
+               <div v-html="display"></div>
+               <button @click="closeRender" class="btn btn-warning" style="position: absolute; right: 0px; top: 0px">Close</button>
+       </div>
+</template>
+<script>
+       import nunjucks from "nunjucks"
+       import dateFilter from "nunjucks-date-filter"
+       export default {
+               props: ["prescription", "template"],
+               data() {
+                       return {
+                               display: ""
+                       }
+               },
+               methods: {
+                       render() {
+                               console.log(this.prescription.prescriber);
+                               console.log(this.template);
+                               fetch("template/"+this.template+".html")
+                                       .then((response)=>response.text())
+                                       .then(function(response) {
+                                               nunjucks.configure({autoescape: true}).addFilter("date", dateFilter);
+                                               var rendered=nunjucks.renderString(response, this.prescription);
+                                               rendered=new DOMParser().parseFromString(rendered, "text/html")
+                                               this.display=rendered.body.innerHTML
+                                       }.bind(this));
+                       },
+                       closeRender() {
+                               this.$emit("closeRender");
+                       }
+               },
+               watch: {
+                       prescription: function() {
+                               this.render();
+                       }
+               }
+       };
+</script>
index 01433bca2ac76590c48fabfee8d69d7b223f48bb..8a8d0de4e79c9c5ef69805837cf88d15b6a15b76 100644 (file)
@@ -1,3 +1,12 @@
+/*
+MedScript Lite
+Copyright (C) 2023 Dr. Agnibho Mondal
+This file is part of MedScript Lite.
+MedScript Lite is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
+MedScript Lite is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+You should have received a copy of the GNU General Public License along with MedScript Lite. If not, see <https://www.gnu.org/licenses/>.
+*/
+
 import { createApp } from 'vue'
 import App from './App.vue'
 
index 910e297e0f53483455d2aa432887c3b7975d6c11..ac5f533f650026757f33dc3ecf9a21e684f182c2 100644 (file)
@@ -1,4 +1,5 @@
 const { defineConfig } = require('@vue/cli-service')
 module.exports = defineConfig({
-  transpileDependencies: true
+  transpileDependencies: true,
+  publicPath: "./"
 })