Initial commit
This commit is contained in:
		
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					*.stl
 | 
				
			||||||
 | 
					docker-compose.yml
 | 
				
			||||||
 | 
					*.py[c|o]
 | 
				
			||||||
 | 
					__pycache__/
 | 
				
			||||||
							
								
								
									
										359
									
								
								COPYING.CC-By-SA
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										359
									
								
								COPYING.CC-By-SA
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,359 @@
 | 
				
			|||||||
 | 
					Creative Commons Legal Code
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Attribution-ShareAlike 3.0 Unported
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
 | 
				
			||||||
 | 
					    LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN
 | 
				
			||||||
 | 
					    ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
 | 
				
			||||||
 | 
					    INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
 | 
				
			||||||
 | 
					    REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR
 | 
				
			||||||
 | 
					    DAMAGES RESULTING FROM ITS USE.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					License
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE
 | 
				
			||||||
 | 
					COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY
 | 
				
			||||||
 | 
					COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS
 | 
				
			||||||
 | 
					AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE
 | 
				
			||||||
 | 
					TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY
 | 
				
			||||||
 | 
					BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS
 | 
				
			||||||
 | 
					CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND
 | 
				
			||||||
 | 
					CONDITIONS.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. Definitions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 a. "Adaptation" means a work based upon the Work, or upon the Work and
 | 
				
			||||||
 | 
					    other pre-existing works, such as a translation, adaptation,
 | 
				
			||||||
 | 
					    derivative work, arrangement of music or other alterations of a
 | 
				
			||||||
 | 
					    literary or artistic work, or phonogram or performance and includes
 | 
				
			||||||
 | 
					    cinematographic adaptations or any other form in which the Work may be
 | 
				
			||||||
 | 
					    recast, transformed, or adapted including in any form recognizably
 | 
				
			||||||
 | 
					    derived from the original, except that a work that constitutes a
 | 
				
			||||||
 | 
					    Collection will not be considered an Adaptation for the purpose of
 | 
				
			||||||
 | 
					    this License. For the avoidance of doubt, where the Work is a musical
 | 
				
			||||||
 | 
					    work, performance or phonogram, the synchronization of the Work in
 | 
				
			||||||
 | 
					    timed-relation with a moving image ("synching") will be considered an
 | 
				
			||||||
 | 
					    Adaptation for the purpose of this License.
 | 
				
			||||||
 | 
					 b. "Collection" means a collection of literary or artistic works, such as
 | 
				
			||||||
 | 
					    encyclopedias and anthologies, or performances, phonograms or
 | 
				
			||||||
 | 
					    broadcasts, or other works or subject matter other than works listed
 | 
				
			||||||
 | 
					    in Section 1(f) below, which, by reason of the selection and
 | 
				
			||||||
 | 
					    arrangement of their contents, constitute intellectual creations, in
 | 
				
			||||||
 | 
					    which the Work is included in its entirety in unmodified form along
 | 
				
			||||||
 | 
					    with one or more other contributions, each constituting separate and
 | 
				
			||||||
 | 
					    independent works in themselves, which together are assembled into a
 | 
				
			||||||
 | 
					    collective whole. A work that constitutes a Collection will not be
 | 
				
			||||||
 | 
					    considered an Adaptation (as defined below) for the purposes of this
 | 
				
			||||||
 | 
					    License.
 | 
				
			||||||
 | 
					 c. "Creative Commons Compatible License" means a license that is listed
 | 
				
			||||||
 | 
					    at https://creativecommons.org/compatiblelicenses that has been
 | 
				
			||||||
 | 
					    approved by Creative Commons as being essentially equivalent to this
 | 
				
			||||||
 | 
					    License, including, at a minimum, because that license: (i) contains
 | 
				
			||||||
 | 
					    terms that have the same purpose, meaning and effect as the License
 | 
				
			||||||
 | 
					    Elements of this License; and, (ii) explicitly permits the relicensing
 | 
				
			||||||
 | 
					    of adaptations of works made available under that license under this
 | 
				
			||||||
 | 
					    License or a Creative Commons jurisdiction license with the same
 | 
				
			||||||
 | 
					    License Elements as this License.
 | 
				
			||||||
 | 
					 d. "Distribute" means to make available to the public the original and
 | 
				
			||||||
 | 
					    copies of the Work or Adaptation, as appropriate, through sale or
 | 
				
			||||||
 | 
					    other transfer of ownership.
 | 
				
			||||||
 | 
					 e. "License Elements" means the following high-level license attributes
 | 
				
			||||||
 | 
					    as selected by Licensor and indicated in the title of this License:
 | 
				
			||||||
 | 
					    Attribution, ShareAlike.
 | 
				
			||||||
 | 
					 f. "Licensor" means the individual, individuals, entity or entities that
 | 
				
			||||||
 | 
					    offer(s) the Work under the terms of this License.
 | 
				
			||||||
 | 
					 g. "Original Author" means, in the case of a literary or artistic work,
 | 
				
			||||||
 | 
					    the individual, individuals, entity or entities who created the Work
 | 
				
			||||||
 | 
					    or if no individual or entity can be identified, the publisher; and in
 | 
				
			||||||
 | 
					    addition (i) in the case of a performance the actors, singers,
 | 
				
			||||||
 | 
					    musicians, dancers, and other persons who act, sing, deliver, declaim,
 | 
				
			||||||
 | 
					    play in, interpret or otherwise perform literary or artistic works or
 | 
				
			||||||
 | 
					    expressions of folklore; (ii) in the case of a phonogram the producer
 | 
				
			||||||
 | 
					    being the person or legal entity who first fixes the sounds of a
 | 
				
			||||||
 | 
					    performance or other sounds; and, (iii) in the case of broadcasts, the
 | 
				
			||||||
 | 
					    organization that transmits the broadcast.
 | 
				
			||||||
 | 
					 h. "Work" means the literary and/or artistic work offered under the terms
 | 
				
			||||||
 | 
					    of this License including without limitation any production in the
 | 
				
			||||||
 | 
					    literary, scientific and artistic domain, whatever may be the mode or
 | 
				
			||||||
 | 
					    form of its expression including digital form, such as a book,
 | 
				
			||||||
 | 
					    pamphlet and other writing; a lecture, address, sermon or other work
 | 
				
			||||||
 | 
					    of the same nature; a dramatic or dramatico-musical work; a
 | 
				
			||||||
 | 
					    choreographic work or entertainment in dumb show; a musical
 | 
				
			||||||
 | 
					    composition with or without words; a cinematographic work to which are
 | 
				
			||||||
 | 
					    assimilated works expressed by a process analogous to cinematography;
 | 
				
			||||||
 | 
					    a work of drawing, painting, architecture, sculpture, engraving or
 | 
				
			||||||
 | 
					    lithography; a photographic work to which are assimilated works
 | 
				
			||||||
 | 
					    expressed by a process analogous to photography; a work of applied
 | 
				
			||||||
 | 
					    art; an illustration, map, plan, sketch or three-dimensional work
 | 
				
			||||||
 | 
					    relative to geography, topography, architecture or science; a
 | 
				
			||||||
 | 
					    performance; a broadcast; a phonogram; a compilation of data to the
 | 
				
			||||||
 | 
					    extent it is protected as a copyrightable work; or a work performed by
 | 
				
			||||||
 | 
					    a variety or circus performer to the extent it is not otherwise
 | 
				
			||||||
 | 
					    considered a literary or artistic work.
 | 
				
			||||||
 | 
					 i. "You" means an individual or entity exercising rights under this
 | 
				
			||||||
 | 
					    License who has not previously violated the terms of this License with
 | 
				
			||||||
 | 
					    respect to the Work, or who has received express permission from the
 | 
				
			||||||
 | 
					    Licensor to exercise rights under this License despite a previous
 | 
				
			||||||
 | 
					    violation.
 | 
				
			||||||
 | 
					 j. "Publicly Perform" means to perform public recitations of the Work and
 | 
				
			||||||
 | 
					    to communicate to the public those public recitations, by any means or
 | 
				
			||||||
 | 
					    process, including by wire or wireless means or public digital
 | 
				
			||||||
 | 
					    performances; to make available to the public Works in such a way that
 | 
				
			||||||
 | 
					    members of the public may access these Works from a place and at a
 | 
				
			||||||
 | 
					    place individually chosen by them; to perform the Work to the public
 | 
				
			||||||
 | 
					    by any means or process and the communication to the public of the
 | 
				
			||||||
 | 
					    performances of the Work, including by public digital performance; to
 | 
				
			||||||
 | 
					    broadcast and rebroadcast the Work by any means including signs,
 | 
				
			||||||
 | 
					    sounds or images.
 | 
				
			||||||
 | 
					 k. "Reproduce" means to make copies of the Work by any means including
 | 
				
			||||||
 | 
					    without limitation by sound or visual recordings and the right of
 | 
				
			||||||
 | 
					    fixation and reproducing fixations of the Work, including storage of a
 | 
				
			||||||
 | 
					    protected performance or phonogram in digital form or other electronic
 | 
				
			||||||
 | 
					    medium.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					2. Fair Dealing Rights. Nothing in this License is intended to reduce,
 | 
				
			||||||
 | 
					limit, or restrict any uses free from copyright or rights arising from
 | 
				
			||||||
 | 
					limitations or exceptions that are provided for in connection with the
 | 
				
			||||||
 | 
					copyright protection under copyright law or other applicable laws.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					3. License Grant. Subject to the terms and conditions of this License,
 | 
				
			||||||
 | 
					Licensor hereby grants You a worldwide, royalty-free, non-exclusive,
 | 
				
			||||||
 | 
					perpetual (for the duration of the applicable copyright) license to
 | 
				
			||||||
 | 
					exercise the rights in the Work as stated below:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 a. to Reproduce the Work, to incorporate the Work into one or more
 | 
				
			||||||
 | 
					    Collections, and to Reproduce the Work as incorporated in the
 | 
				
			||||||
 | 
					    Collections;
 | 
				
			||||||
 | 
					 b. to create and Reproduce Adaptations provided that any such Adaptation,
 | 
				
			||||||
 | 
					    including any translation in any medium, takes reasonable steps to
 | 
				
			||||||
 | 
					    clearly label, demarcate or otherwise identify that changes were made
 | 
				
			||||||
 | 
					    to the original Work. For example, a translation could be marked "The
 | 
				
			||||||
 | 
					    original work was translated from English to Spanish," or a
 | 
				
			||||||
 | 
					    modification could indicate "The original work has been modified.";
 | 
				
			||||||
 | 
					 c. to Distribute and Publicly Perform the Work including as incorporated
 | 
				
			||||||
 | 
					    in Collections; and,
 | 
				
			||||||
 | 
					 d. to Distribute and Publicly Perform Adaptations.
 | 
				
			||||||
 | 
					 e. For the avoidance of doubt:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					     i. Non-waivable Compulsory License Schemes. In those jurisdictions in
 | 
				
			||||||
 | 
					        which the right to collect royalties through any statutory or
 | 
				
			||||||
 | 
					        compulsory licensing scheme cannot be waived, the Licensor
 | 
				
			||||||
 | 
					        reserves the exclusive right to collect such royalties for any
 | 
				
			||||||
 | 
					        exercise by You of the rights granted under this License;
 | 
				
			||||||
 | 
					    ii. Waivable Compulsory License Schemes. In those jurisdictions in
 | 
				
			||||||
 | 
					        which the right to collect royalties through any statutory or
 | 
				
			||||||
 | 
					        compulsory licensing scheme can be waived, the Licensor waives the
 | 
				
			||||||
 | 
					        exclusive right to collect such royalties for any exercise by You
 | 
				
			||||||
 | 
					        of the rights granted under this License; and,
 | 
				
			||||||
 | 
					   iii. Voluntary License Schemes. The Licensor waives the right to
 | 
				
			||||||
 | 
					        collect royalties, whether individually or, in the event that the
 | 
				
			||||||
 | 
					        Licensor is a member of a collecting society that administers
 | 
				
			||||||
 | 
					        voluntary licensing schemes, via that society, from any exercise
 | 
				
			||||||
 | 
					        by You of the rights granted under this License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The above rights may be exercised in all media and formats whether now
 | 
				
			||||||
 | 
					known or hereafter devised. The above rights include the right to make
 | 
				
			||||||
 | 
					such modifications as are technically necessary to exercise the rights in
 | 
				
			||||||
 | 
					other media and formats. Subject to Section 8(f), all rights not expressly
 | 
				
			||||||
 | 
					granted by Licensor are hereby reserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					4. Restrictions. The license granted in Section 3 above is expressly made
 | 
				
			||||||
 | 
					subject to and limited by the following restrictions:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 a. You may Distribute or Publicly Perform the Work only under the terms
 | 
				
			||||||
 | 
					    of this License. You must include a copy of, or the Uniform Resource
 | 
				
			||||||
 | 
					    Identifier (URI) for, this License with every copy of the Work You
 | 
				
			||||||
 | 
					    Distribute or Publicly Perform. You may not offer or impose any terms
 | 
				
			||||||
 | 
					    on the Work that restrict the terms of this License or the ability of
 | 
				
			||||||
 | 
					    the recipient of the Work to exercise the rights granted to that
 | 
				
			||||||
 | 
					    recipient under the terms of the License. You may not sublicense the
 | 
				
			||||||
 | 
					    Work. You must keep intact all notices that refer to this License and
 | 
				
			||||||
 | 
					    to the disclaimer of warranties with every copy of the Work You
 | 
				
			||||||
 | 
					    Distribute or Publicly Perform. When You Distribute or Publicly
 | 
				
			||||||
 | 
					    Perform the Work, You may not impose any effective technological
 | 
				
			||||||
 | 
					    measures on the Work that restrict the ability of a recipient of the
 | 
				
			||||||
 | 
					    Work from You to exercise the rights granted to that recipient under
 | 
				
			||||||
 | 
					    the terms of the License. This Section 4(a) applies to the Work as
 | 
				
			||||||
 | 
					    incorporated in a Collection, but this does not require the Collection
 | 
				
			||||||
 | 
					    apart from the Work itself to be made subject to the terms of this
 | 
				
			||||||
 | 
					    License. If You create a Collection, upon notice from any Licensor You
 | 
				
			||||||
 | 
					    must, to the extent practicable, remove from the Collection any credit
 | 
				
			||||||
 | 
					    as required by Section 4(c), as requested. If You create an
 | 
				
			||||||
 | 
					    Adaptation, upon notice from any Licensor You must, to the extent
 | 
				
			||||||
 | 
					    practicable, remove from the Adaptation any credit as required by
 | 
				
			||||||
 | 
					    Section 4(c), as requested.
 | 
				
			||||||
 | 
					 b. You may Distribute or Publicly Perform an Adaptation only under the
 | 
				
			||||||
 | 
					    terms of: (i) this License; (ii) a later version of this License with
 | 
				
			||||||
 | 
					    the same License Elements as this License; (iii) a Creative Commons
 | 
				
			||||||
 | 
					    jurisdiction license (either this or a later license version) that
 | 
				
			||||||
 | 
					    contains the same License Elements as this License (e.g.,
 | 
				
			||||||
 | 
					    Attribution-ShareAlike 3.0 US)); (iv) a Creative Commons Compatible
 | 
				
			||||||
 | 
					    License. If you license the Adaptation under one of the licenses
 | 
				
			||||||
 | 
					    mentioned in (iv), you must comply with the terms of that license. If
 | 
				
			||||||
 | 
					    you license the Adaptation under the terms of any of the licenses
 | 
				
			||||||
 | 
					    mentioned in (i), (ii) or (iii) (the "Applicable License"), you must
 | 
				
			||||||
 | 
					    comply with the terms of the Applicable License generally and the
 | 
				
			||||||
 | 
					    following provisions: (I) You must include a copy of, or the URI for,
 | 
				
			||||||
 | 
					    the Applicable License with every copy of each Adaptation You
 | 
				
			||||||
 | 
					    Distribute or Publicly Perform; (II) You may not offer or impose any
 | 
				
			||||||
 | 
					    terms on the Adaptation that restrict the terms of the Applicable
 | 
				
			||||||
 | 
					    License or the ability of the recipient of the Adaptation to exercise
 | 
				
			||||||
 | 
					    the rights granted to that recipient under the terms of the Applicable
 | 
				
			||||||
 | 
					    License; (III) You must keep intact all notices that refer to the
 | 
				
			||||||
 | 
					    Applicable License and to the disclaimer of warranties with every copy
 | 
				
			||||||
 | 
					    of the Work as included in the Adaptation You Distribute or Publicly
 | 
				
			||||||
 | 
					    Perform; (IV) when You Distribute or Publicly Perform the Adaptation,
 | 
				
			||||||
 | 
					    You may not impose any effective technological measures on the
 | 
				
			||||||
 | 
					    Adaptation that restrict the ability of a recipient of the Adaptation
 | 
				
			||||||
 | 
					    from You to exercise the rights granted to that recipient under the
 | 
				
			||||||
 | 
					    terms of the Applicable License. This Section 4(b) applies to the
 | 
				
			||||||
 | 
					    Adaptation as incorporated in a Collection, but this does not require
 | 
				
			||||||
 | 
					    the Collection apart from the Adaptation itself to be made subject to
 | 
				
			||||||
 | 
					    the terms of the Applicable License.
 | 
				
			||||||
 | 
					 c. If You Distribute, or Publicly Perform the Work or any Adaptations or
 | 
				
			||||||
 | 
					    Collections, You must, unless a request has been made pursuant to
 | 
				
			||||||
 | 
					    Section 4(a), keep intact all copyright notices for the Work and
 | 
				
			||||||
 | 
					    provide, reasonable to the medium or means You are utilizing: (i) the
 | 
				
			||||||
 | 
					    name of the Original Author (or pseudonym, if applicable) if supplied,
 | 
				
			||||||
 | 
					    and/or if the Original Author and/or Licensor designate another party
 | 
				
			||||||
 | 
					    or parties (e.g., a sponsor institute, publishing entity, journal) for
 | 
				
			||||||
 | 
					    attribution ("Attribution Parties") in Licensor's copyright notice,
 | 
				
			||||||
 | 
					    terms of service or by other reasonable means, the name of such party
 | 
				
			||||||
 | 
					    or parties; (ii) the title of the Work if supplied; (iii) to the
 | 
				
			||||||
 | 
					    extent reasonably practicable, the URI, if any, that Licensor
 | 
				
			||||||
 | 
					    specifies to be associated with the Work, unless such URI does not
 | 
				
			||||||
 | 
					    refer to the copyright notice or licensing information for the Work;
 | 
				
			||||||
 | 
					    and (iv) , consistent with Ssection 3(b), in the case of an
 | 
				
			||||||
 | 
					    Adaptation, a credit identifying the use of the Work in the Adaptation
 | 
				
			||||||
 | 
					    (e.g., "French translation of the Work by Original Author," or
 | 
				
			||||||
 | 
					    "Screenplay based on original Work by Original Author"). The credit
 | 
				
			||||||
 | 
					    required by this Section 4(c) may be implemented in any reasonable
 | 
				
			||||||
 | 
					    manner; provided, however, that in the case of a Adaptation or
 | 
				
			||||||
 | 
					    Collection, at a minimum such credit will appear, if a credit for all
 | 
				
			||||||
 | 
					    contributing authors of the Adaptation or Collection appears, then as
 | 
				
			||||||
 | 
					    part of these credits and in a manner at least as prominent as the
 | 
				
			||||||
 | 
					    credits for the other contributing authors. For the avoidance of
 | 
				
			||||||
 | 
					    doubt, You may only use the credit required by this Section for the
 | 
				
			||||||
 | 
					    purpose of attribution in the manner set out above and, by exercising
 | 
				
			||||||
 | 
					    Your rights under this License, You may not implicitly or explicitly
 | 
				
			||||||
 | 
					    assert or imply any connection with, sponsorship or endorsement by the
 | 
				
			||||||
 | 
					    Original Author, Licensor and/or Attribution Parties, as appropriate,
 | 
				
			||||||
 | 
					    of You or Your use of the Work, without the separate, express prior
 | 
				
			||||||
 | 
					    written permission of the Original Author, Licensor and/or Attribution
 | 
				
			||||||
 | 
					    Parties.
 | 
				
			||||||
 | 
					 d. Except as otherwise agreed in writing by the Licensor or as may be
 | 
				
			||||||
 | 
					    otherwise permitted by applicable law, if You Reproduce, Distribute or
 | 
				
			||||||
 | 
					    Publicly Perform the Work either by itself or as part of any
 | 
				
			||||||
 | 
					    Adaptations or Collections, You must not distort, mutilate, modify or
 | 
				
			||||||
 | 
					    take other derogatory action in relation to the Work which would be
 | 
				
			||||||
 | 
					    prejudicial to the Original Author's honor or reputation. Licensor
 | 
				
			||||||
 | 
					    agrees that in those jurisdictions (e.g. Japan), in which any exercise
 | 
				
			||||||
 | 
					    of the right granted in Section 3(b) of this License (the right to
 | 
				
			||||||
 | 
					    make Adaptations) would be deemed to be a distortion, mutilation,
 | 
				
			||||||
 | 
					    modification or other derogatory action prejudicial to the Original
 | 
				
			||||||
 | 
					    Author's honor and reputation, the Licensor will waive or not assert,
 | 
				
			||||||
 | 
					    as appropriate, this Section, to the fullest extent permitted by the
 | 
				
			||||||
 | 
					    applicable national law, to enable You to reasonably exercise Your
 | 
				
			||||||
 | 
					    right under Section 3(b) of this License (right to make Adaptations)
 | 
				
			||||||
 | 
					    but not otherwise.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					5. Representations, Warranties and Disclaimer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR
 | 
				
			||||||
 | 
					OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY
 | 
				
			||||||
 | 
					KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE,
 | 
				
			||||||
 | 
					INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY,
 | 
				
			||||||
 | 
					FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF
 | 
				
			||||||
 | 
					LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS,
 | 
				
			||||||
 | 
					WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION
 | 
				
			||||||
 | 
					OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE
 | 
				
			||||||
 | 
					LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR
 | 
				
			||||||
 | 
					ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES
 | 
				
			||||||
 | 
					ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS
 | 
				
			||||||
 | 
					BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					7. Termination
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 a. This License and the rights granted hereunder will terminate
 | 
				
			||||||
 | 
					    automatically upon any breach by You of the terms of this License.
 | 
				
			||||||
 | 
					    Individuals or entities who have received Adaptations or Collections
 | 
				
			||||||
 | 
					    from You under this License, however, will not have their licenses
 | 
				
			||||||
 | 
					    terminated provided such individuals or entities remain in full
 | 
				
			||||||
 | 
					    compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will
 | 
				
			||||||
 | 
					    survive any termination of this License.
 | 
				
			||||||
 | 
					 b. Subject to the above terms and conditions, the license granted here is
 | 
				
			||||||
 | 
					    perpetual (for the duration of the applicable copyright in the Work).
 | 
				
			||||||
 | 
					    Notwithstanding the above, Licensor reserves the right to release the
 | 
				
			||||||
 | 
					    Work under different license terms or to stop distributing the Work at
 | 
				
			||||||
 | 
					    any time; provided, however that any such election will not serve to
 | 
				
			||||||
 | 
					    withdraw this License (or any other license that has been, or is
 | 
				
			||||||
 | 
					    required to be, granted under the terms of this License), and this
 | 
				
			||||||
 | 
					    License will continue in full force and effect unless terminated as
 | 
				
			||||||
 | 
					    stated above.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					8. Miscellaneous
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 a. Each time You Distribute or Publicly Perform the Work or a Collection,
 | 
				
			||||||
 | 
					    the Licensor offers to the recipient a license to the Work on the same
 | 
				
			||||||
 | 
					    terms and conditions as the license granted to You under this License.
 | 
				
			||||||
 | 
					 b. Each time You Distribute or Publicly Perform an Adaptation, Licensor
 | 
				
			||||||
 | 
					    offers to the recipient a license to the original Work on the same
 | 
				
			||||||
 | 
					    terms and conditions as the license granted to You under this License.
 | 
				
			||||||
 | 
					 c. If any provision of this License is invalid or unenforceable under
 | 
				
			||||||
 | 
					    applicable law, it shall not affect the validity or enforceability of
 | 
				
			||||||
 | 
					    the remainder of the terms of this License, and without further action
 | 
				
			||||||
 | 
					    by the parties to this agreement, such provision shall be reformed to
 | 
				
			||||||
 | 
					    the minimum extent necessary to make such provision valid and
 | 
				
			||||||
 | 
					    enforceable.
 | 
				
			||||||
 | 
					 d. No term or provision of this License shall be deemed waived and no
 | 
				
			||||||
 | 
					    breach consented to unless such waiver or consent shall be in writing
 | 
				
			||||||
 | 
					    and signed by the party to be charged with such waiver or consent.
 | 
				
			||||||
 | 
					 e. This License constitutes the entire agreement between the parties with
 | 
				
			||||||
 | 
					    respect to the Work licensed here. There are no understandings,
 | 
				
			||||||
 | 
					    agreements or representations with respect to the Work not specified
 | 
				
			||||||
 | 
					    here. Licensor shall not be bound by any additional provisions that
 | 
				
			||||||
 | 
					    may appear in any communication from You. This License may not be
 | 
				
			||||||
 | 
					    modified without the mutual written agreement of the Licensor and You.
 | 
				
			||||||
 | 
					 f. The rights granted under, and the subject matter referenced, in this
 | 
				
			||||||
 | 
					    License were drafted utilizing the terminology of the Berne Convention
 | 
				
			||||||
 | 
					    for the Protection of Literary and Artistic Works (as amended on
 | 
				
			||||||
 | 
					    September 28, 1979), the Rome Convention of 1961, the WIPO Copyright
 | 
				
			||||||
 | 
					    Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996
 | 
				
			||||||
 | 
					    and the Universal Copyright Convention (as revised on July 24, 1971).
 | 
				
			||||||
 | 
					    These rights and subject matter take effect in the relevant
 | 
				
			||||||
 | 
					    jurisdiction in which the License terms are sought to be enforced
 | 
				
			||||||
 | 
					    according to the corresponding provisions of the implementation of
 | 
				
			||||||
 | 
					    those treaty provisions in the applicable national law. If the
 | 
				
			||||||
 | 
					    standard suite of rights granted under applicable copyright law
 | 
				
			||||||
 | 
					    includes additional rights not granted under this License, such
 | 
				
			||||||
 | 
					    additional rights are deemed to be included in the License; this
 | 
				
			||||||
 | 
					    License is not intended to restrict the license of any rights under
 | 
				
			||||||
 | 
					    applicable law.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Creative Commons Notice
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Creative Commons is not a party to this License, and makes no warranty
 | 
				
			||||||
 | 
					    whatsoever in connection with the Work. Creative Commons will not be
 | 
				
			||||||
 | 
					    liable to You or any party on any legal theory for any damages
 | 
				
			||||||
 | 
					    whatsoever, including without limitation any general, special,
 | 
				
			||||||
 | 
					    incidental or consequential damages arising in connection to this
 | 
				
			||||||
 | 
					    license. Notwithstanding the foregoing two (2) sentences, if Creative
 | 
				
			||||||
 | 
					    Commons has expressly identified itself as the Licensor hereunder, it
 | 
				
			||||||
 | 
					    shall have all rights and obligations of Licensor.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Except for the limited purpose of indicating to the public that the
 | 
				
			||||||
 | 
					    Work is licensed under the CCPL, Creative Commons does not authorize
 | 
				
			||||||
 | 
					    the use by either party of the trademark "Creative Commons" or any
 | 
				
			||||||
 | 
					    related trademark or logo of Creative Commons without the prior
 | 
				
			||||||
 | 
					    written consent of Creative Commons. Any permitted use will be in
 | 
				
			||||||
 | 
					    compliance with Creative Commons' then-current trademark usage
 | 
				
			||||||
 | 
					    guidelines, as may be published on its website or otherwise made
 | 
				
			||||||
 | 
					    available upon request from time to time. For the avoidance of doubt,
 | 
				
			||||||
 | 
					    this trademark restriction does not form part of the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Creative Commons may be contacted at https://creativecommons.org/.
 | 
				
			||||||
							
								
								
									
										121
									
								
								COPYING.CC0
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								COPYING.CC0
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,121 @@
 | 
				
			|||||||
 | 
					Creative Commons Legal Code
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CC0 1.0 Universal
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
 | 
				
			||||||
 | 
					    LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
 | 
				
			||||||
 | 
					    ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
 | 
				
			||||||
 | 
					    INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
 | 
				
			||||||
 | 
					    REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
 | 
				
			||||||
 | 
					    PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
 | 
				
			||||||
 | 
					    THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
 | 
				
			||||||
 | 
					    HEREUNDER.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Statement of Purpose
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The laws of most jurisdictions throughout the world automatically confer
 | 
				
			||||||
 | 
					exclusive Copyright and Related Rights (defined below) upon the creator
 | 
				
			||||||
 | 
					and subsequent owner(s) (each and all, an "owner") of an original work of
 | 
				
			||||||
 | 
					authorship and/or a database (each, a "Work").
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Certain owners wish to permanently relinquish those rights to a Work for
 | 
				
			||||||
 | 
					the purpose of contributing to a commons of creative, cultural and
 | 
				
			||||||
 | 
					scientific works ("Commons") that the public can reliably and without fear
 | 
				
			||||||
 | 
					of later claims of infringement build upon, modify, incorporate in other
 | 
				
			||||||
 | 
					works, reuse and redistribute as freely as possible in any form whatsoever
 | 
				
			||||||
 | 
					and for any purposes, including without limitation commercial purposes.
 | 
				
			||||||
 | 
					These owners may contribute to the Commons to promote the ideal of a free
 | 
				
			||||||
 | 
					culture and the further production of creative, cultural and scientific
 | 
				
			||||||
 | 
					works, or to gain reputation or greater distribution for their Work in
 | 
				
			||||||
 | 
					part through the use and efforts of others.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For these and/or other purposes and motivations, and without any
 | 
				
			||||||
 | 
					expectation of additional consideration or compensation, the person
 | 
				
			||||||
 | 
					associating CC0 with a Work (the "Affirmer"), to the extent that he or she
 | 
				
			||||||
 | 
					is an owner of Copyright and Related Rights in the Work, voluntarily
 | 
				
			||||||
 | 
					elects to apply CC0 to the Work and publicly distribute the Work under its
 | 
				
			||||||
 | 
					terms, with knowledge of his or her Copyright and Related Rights in the
 | 
				
			||||||
 | 
					Work and the meaning and intended legal effect of CC0 on those rights.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. Copyright and Related Rights. A Work made available under CC0 may be
 | 
				
			||||||
 | 
					protected by copyright and related or neighboring rights ("Copyright and
 | 
				
			||||||
 | 
					Related Rights"). Copyright and Related Rights include, but are not
 | 
				
			||||||
 | 
					limited to, the following:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  i. the right to reproduce, adapt, distribute, perform, display,
 | 
				
			||||||
 | 
					     communicate, and translate a Work;
 | 
				
			||||||
 | 
					 ii. moral rights retained by the original author(s) and/or performer(s);
 | 
				
			||||||
 | 
					iii. publicity and privacy rights pertaining to a person's image or
 | 
				
			||||||
 | 
					     likeness depicted in a Work;
 | 
				
			||||||
 | 
					 iv. rights protecting against unfair competition in regards to a Work,
 | 
				
			||||||
 | 
					     subject to the limitations in paragraph 4(a), below;
 | 
				
			||||||
 | 
					  v. rights protecting the extraction, dissemination, use and reuse of data
 | 
				
			||||||
 | 
					     in a Work;
 | 
				
			||||||
 | 
					 vi. database rights (such as those arising under Directive 96/9/EC of the
 | 
				
			||||||
 | 
					     European Parliament and of the Council of 11 March 1996 on the legal
 | 
				
			||||||
 | 
					     protection of databases, and under any national implementation
 | 
				
			||||||
 | 
					     thereof, including any amended or successor version of such
 | 
				
			||||||
 | 
					     directive); and
 | 
				
			||||||
 | 
					vii. other similar, equivalent or corresponding rights throughout the
 | 
				
			||||||
 | 
					     world based on applicable law or treaty, and any national
 | 
				
			||||||
 | 
					     implementations thereof.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					2. Waiver. To the greatest extent permitted by, but not in contravention
 | 
				
			||||||
 | 
					of, applicable law, Affirmer hereby overtly, fully, permanently,
 | 
				
			||||||
 | 
					irrevocably and unconditionally waives, abandons, and surrenders all of
 | 
				
			||||||
 | 
					Affirmer's Copyright and Related Rights and associated claims and causes
 | 
				
			||||||
 | 
					of action, whether now known or unknown (including existing as well as
 | 
				
			||||||
 | 
					future claims and causes of action), in the Work (i) in all territories
 | 
				
			||||||
 | 
					worldwide, (ii) for the maximum duration provided by applicable law or
 | 
				
			||||||
 | 
					treaty (including future time extensions), (iii) in any current or future
 | 
				
			||||||
 | 
					medium and for any number of copies, and (iv) for any purpose whatsoever,
 | 
				
			||||||
 | 
					including without limitation commercial, advertising or promotional
 | 
				
			||||||
 | 
					purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
 | 
				
			||||||
 | 
					member of the public at large and to the detriment of Affirmer's heirs and
 | 
				
			||||||
 | 
					successors, fully intending that such Waiver shall not be subject to
 | 
				
			||||||
 | 
					revocation, rescission, cancellation, termination, or any other legal or
 | 
				
			||||||
 | 
					equitable action to disrupt the quiet enjoyment of the Work by the public
 | 
				
			||||||
 | 
					as contemplated by Affirmer's express Statement of Purpose.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					3. Public License Fallback. Should any part of the Waiver for any reason
 | 
				
			||||||
 | 
					be judged legally invalid or ineffective under applicable law, then the
 | 
				
			||||||
 | 
					Waiver shall be preserved to the maximum extent permitted taking into
 | 
				
			||||||
 | 
					account Affirmer's express Statement of Purpose. In addition, to the
 | 
				
			||||||
 | 
					extent the Waiver is so judged Affirmer hereby grants to each affected
 | 
				
			||||||
 | 
					person a royalty-free, non transferable, non sublicensable, non exclusive,
 | 
				
			||||||
 | 
					irrevocable and unconditional license to exercise Affirmer's Copyright and
 | 
				
			||||||
 | 
					Related Rights in the Work (i) in all territories worldwide, (ii) for the
 | 
				
			||||||
 | 
					maximum duration provided by applicable law or treaty (including future
 | 
				
			||||||
 | 
					time extensions), (iii) in any current or future medium and for any number
 | 
				
			||||||
 | 
					of copies, and (iv) for any purpose whatsoever, including without
 | 
				
			||||||
 | 
					limitation commercial, advertising or promotional purposes (the
 | 
				
			||||||
 | 
					"License"). The License shall be deemed effective as of the date CC0 was
 | 
				
			||||||
 | 
					applied by Affirmer to the Work. Should any part of the License for any
 | 
				
			||||||
 | 
					reason be judged legally invalid or ineffective under applicable law, such
 | 
				
			||||||
 | 
					partial invalidity or ineffectiveness shall not invalidate the remainder
 | 
				
			||||||
 | 
					of the License, and in such case Affirmer hereby affirms that he or she
 | 
				
			||||||
 | 
					will not (i) exercise any of his or her remaining Copyright and Related
 | 
				
			||||||
 | 
					Rights in the Work or (ii) assert any associated claims and causes of
 | 
				
			||||||
 | 
					action with respect to the Work, in either case contrary to Affirmer's
 | 
				
			||||||
 | 
					express Statement of Purpose.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					4. Limitations and Disclaimers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 a. No trademark or patent rights held by Affirmer are waived, abandoned,
 | 
				
			||||||
 | 
					    surrendered, licensed or otherwise affected by this document.
 | 
				
			||||||
 | 
					 b. Affirmer offers the Work as-is and makes no representations or
 | 
				
			||||||
 | 
					    warranties of any kind concerning the Work, express, implied,
 | 
				
			||||||
 | 
					    statutory or otherwise, including without limitation warranties of
 | 
				
			||||||
 | 
					    title, merchantability, fitness for a particular purpose, non
 | 
				
			||||||
 | 
					    infringement, or the absence of latent or other defects, accuracy, or
 | 
				
			||||||
 | 
					    the present or absence of errors, whether or not discoverable, all to
 | 
				
			||||||
 | 
					    the greatest extent permissible under applicable law.
 | 
				
			||||||
 | 
					 c. Affirmer disclaims responsibility for clearing rights of other persons
 | 
				
			||||||
 | 
					    that may apply to the Work or any use thereof, including without
 | 
				
			||||||
 | 
					    limitation any person's Copyright and Related Rights in the Work.
 | 
				
			||||||
 | 
					    Further, Affirmer disclaims responsibility for obtaining any necessary
 | 
				
			||||||
 | 
					    consents, permissions or other rights required for any use of the
 | 
				
			||||||
 | 
					    Work.
 | 
				
			||||||
 | 
					 d. Affirmer understands and acknowledges that Creative Commons is not a
 | 
				
			||||||
 | 
					    party to this document and has no duty or obligation with respect to
 | 
				
			||||||
 | 
					    this CC0 or use of the Work.
 | 
				
			||||||
							
								
								
									
										17
									
								
								Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								Dockerfile
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					FROM python:3.11-alpine
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN apk add poetry && \
 | 
				
			||||||
 | 
					    apk add --repository=http://dl-cdn.alpinelinux.org/alpine/edge/testing/ openscad
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# switch users
 | 
				
			||||||
 | 
					RUN adduser -S app && \
 | 
				
			||||||
 | 
					    install -D -d -o app /app \
 | 
				
			||||||
 | 
					USER app
 | 
				
			||||||
 | 
					WORKDIR /app
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					COPY pyproject.toml poetry.lock README.md /app/
 | 
				
			||||||
 | 
					COPY app/ /app/app/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RUN poetry install
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CMD poetry run uvicorn --host 0.0.0.0 --port 8000 app.app:app
 | 
				
			||||||
							
								
								
									
										20
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					# FabLab Bottle Clip Generator
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This project renders bottle clips for a given name with the widely known FabLab "cube" logo.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The generator allows users to generate and download STL files generated on the server using
 | 
				
			||||||
 | 
					[OpenSCAD](https://openscad.org/) and the
 | 
				
			||||||
 | 
					[parametric bottle name tag](https://www.thingiverse.com/thing:38861) project.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Licensing
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The OpenSCAD code of the parametric bottle clip generator is licensed under the terms of the
 | 
				
			||||||
 | 
					[CC-By-SA 3.0 Unported license](https://creativecommons.org/licenses/by-sa/3.0/). A copy of the license can be found
 | 
				
			||||||
 | 
					in `COPYING.CC-By-SA`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The remaining Python code is licensed under the terms of the [CC0](https://creativecommons.org/publicdomain/zero/1.0/)
 | 
				
			||||||
 | 
					license. A copy of the license can be found in `COPYING.CC0`.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The FabLab "cube logo" is not subject to copyright protection and is considered to be in the public domain. The
 | 
				
			||||||
 | 
					drawings derived from it which this project uses are in the public domain as well.
 | 
				
			||||||
							
								
								
									
										0
									
								
								app/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								app/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										4
									
								
								app/__main__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								app/__main__.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					from .app import app
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					app.run(debug=True)
 | 
				
			||||||
							
								
								
									
										124
									
								
								app/app.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								app/app.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,124 @@
 | 
				
			|||||||
 | 
					import asyncio
 | 
				
			||||||
 | 
					import io
 | 
				
			||||||
 | 
					import shutil
 | 
				
			||||||
 | 
					import tempfile
 | 
				
			||||||
 | 
					from distutils.dir_util import copy_tree
 | 
				
			||||||
 | 
					from pathlib import Path
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from quart import Quart, abort, send_file, render_template, request
 | 
				
			||||||
 | 
					from werkzeug.utils import secure_filename
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					app = Quart(__name__, static_folder="static", template_folder="templates")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# allow at most these many scad processes in parallel
 | 
				
			||||||
 | 
					semaphore = asyncio.Semaphore(2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def package_path() -> Path:
 | 
				
			||||||
 | 
					    return Path(__file__).parent
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Generator:
 | 
				
			||||||
 | 
					    GENERATOR_SCAD_FILE_NAME = "generator.scad"
 | 
				
			||||||
 | 
					    GENERATED_STL_FILE_NAME = "generated.stl"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, name: str, tempdir: Path | str):
 | 
				
			||||||
 | 
					        self._name = name
 | 
				
			||||||
 | 
					        self._tempdir = Path(tempdir)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _generate_scad_template(self) -> str:
 | 
				
			||||||
 | 
					        return f"""
 | 
				
			||||||
 | 
					            use <bottle-clip.scad>
 | 
				
			||||||
 | 
					            $fn=180;
 | 
				
			||||||
 | 
					            // one name tag for 0.5l Club Mate and similar bottles
 | 
				
			||||||
 | 
					            bottle_clip(name="{self._name}", logo="thing-logos/fablab-cube2.dxf");
 | 
				
			||||||
 | 
					        """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _generate_files_in_temp_dir(self):
 | 
				
			||||||
 | 
					        copy_tree(str(package_path() / "openscad"), str(self._tempdir))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        with open(self._tempdir / self.GENERATOR_SCAD_FILE_NAME, "w") as f:
 | 
				
			||||||
 | 
					            f.write(self._generate_scad_template())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def generate_stl(self) -> str:
 | 
				
			||||||
 | 
					        self._generate_files_in_temp_dir()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        openscad_path = shutil.which("openscad")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if not openscad_path:
 | 
				
			||||||
 | 
					            abort(500)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        proc = await asyncio.create_subprocess_exec(
 | 
				
			||||||
 | 
					            openscad_path,
 | 
				
			||||||
 | 
					            self.GENERATOR_SCAD_FILE_NAME,
 | 
				
			||||||
 | 
					            "-o",
 | 
				
			||||||
 | 
					            self.GENERATED_STL_FILE_NAME,
 | 
				
			||||||
 | 
					            # "--hardwarnings",
 | 
				
			||||||
 | 
					            cwd=self._tempdir,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        await proc.wait()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if proc.returncode != 0:
 | 
				
			||||||
 | 
					            abort(500)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return self.GENERATED_STL_FILE_NAME
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@app.route("/generate/<name>")
 | 
				
			||||||
 | 
					async def generate_rest(name: str):
 | 
				
			||||||
 | 
					    async with semaphore:
 | 
				
			||||||
 | 
					        with tempfile.TemporaryDirectory(prefix="fablab-bottle-clip-generator-") as tempdir:
 | 
				
			||||||
 | 
					            generator = Generator(name, tempdir)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            generated_stl_file_name = await generator.generate_stl()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # to be able to use send_file with a temporary directory, we need buffer the entire file in memory
 | 
				
			||||||
 | 
					            # before the context manager gets to delete the dir
 | 
				
			||||||
 | 
					            bytes_io = io.BytesIO()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            with open(Path(tempdir) / generated_stl_file_name, "rb") as f:
 | 
				
			||||||
 | 
					                while True:
 | 
				
			||||||
 | 
					                    data = f.read(4096)
 | 
				
			||||||
 | 
					                    if not data:
 | 
				
			||||||
 | 
					                        break
 | 
				
			||||||
 | 
					                    bytes_io.write(data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # using secure_filename allows us to send the file to the user with some safe yet reasonably
 | 
				
			||||||
 | 
					            # identifiable filename
 | 
				
			||||||
 | 
					            return await send_file(
 | 
				
			||||||
 | 
					                bytes_io,
 | 
				
			||||||
 | 
					                mimetype="model/stl",
 | 
				
			||||||
 | 
					                as_attachment=True,
 | 
				
			||||||
 | 
					                attachment_filename=secure_filename(f"{name}.stl")
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# aside from the RESTful API above, we need a "traditional" HTML forms compatible end point
 | 
				
			||||||
 | 
					@app.route("/generate")
 | 
				
			||||||
 | 
					async def generate_form():
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        name = request.args["name"]
 | 
				
			||||||
 | 
					    except KeyError:
 | 
				
			||||||
 | 
					        abort(400)
 | 
				
			||||||
 | 
					        return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return await generate_rest(name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@app.route("/")
 | 
				
			||||||
 | 
					async def index():
 | 
				
			||||||
 | 
					    return await render_template("index.html")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					async def test():
 | 
				
			||||||
 | 
					    with tempfile.TemporaryDirectory() as td:
 | 
				
			||||||
 | 
					        generator = Generator("testabc", td)
 | 
				
			||||||
 | 
					        generated_stl_file_name = await generator.generate_stl()
 | 
				
			||||||
 | 
					        shutil.copy(Path(td) / generated_stl_file_name, ".")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == "__main__":
 | 
				
			||||||
 | 
					    import asyncio
 | 
				
			||||||
 | 
					    asyncio.run(test())
 | 
				
			||||||
							
								
								
									
										119
									
								
								app/openscad/bottle-clip.scad
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								app/openscad/bottle-clip.scad
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,119 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * A name tag that can easily be clipped to the neck of your bottle.
 | 
				
			||||||
 | 
					 * Copyright (C) 2013 Roland Hieber <rohieb+bottleclip@rohieb.name>
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * See examples.scad for examples on how to use this module.
 | 
				
			||||||
 | 
					 *
 | 
				
			||||||
 | 
					 * The contents of this file are licenced under CC-BY-SA 3.0 Unported.
 | 
				
			||||||
 | 
					 * See https://creativecommons.org/licenses/by-sa/3.0/deed for the
 | 
				
			||||||
 | 
					 * licensing terms.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					include <write/Write.scad>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Creates one instance of a bottle clip name tag. The default values are
 | 
				
			||||||
 | 
					 * suitable for 0.5l Club Mate bottles (and similar bottles). By default, logo
 | 
				
			||||||
 | 
					 * and text are placed on the name tag so they both share half the height. If
 | 
				
			||||||
 | 
					 * there is no logo, the text uses the total height instead.
 | 
				
			||||||
 | 
					 * Parameters:
 | 
				
			||||||
 | 
					 * ru: the radius on the upper side of the clip
 | 
				
			||||||
 | 
					 * rl: the radius on the lower side of the clip
 | 
				
			||||||
 | 
					 * ht: the height of the clip
 | 
				
			||||||
 | 
					 * width: the thickness of the wall. Values near 2.5 usually result in a good
 | 
				
			||||||
 | 
					 *	clippiness for PLA prints.
 | 
				
			||||||
 | 
					 * name: the name that is printed on your name tag. For the default ru/rt/ht
 | 
				
			||||||
 | 
					 *	values, this string should not exceed 18 characters to fit on the name tag.
 | 
				
			||||||
 | 
					 * gap: width of the opening gap, in degrees. For rigid materials this value
 | 
				
			||||||
 | 
					 *  usually needs to be near 180 (but if you set it to >= 180, you won't have
 | 
				
			||||||
 | 
					 *  anything left for holding the clip on the bottle). For flexible materials
 | 
				
			||||||
 | 
					 *  like Ninjaflex, choose something near 0. For springy materials like PLA or
 | 
				
			||||||
 | 
					 *  ABS, 90 has proven to be a good value.
 | 
				
			||||||
 | 
					 * logo: the path to a DXF file representing a logo that should be put above
 | 
				
			||||||
 | 
					 *	the name. Logo files should be no larger than 50 units in height and should
 | 
				
			||||||
 | 
					 *	be centered on the point (25,25). Also all units in the DXF file should be
 | 
				
			||||||
 | 
					 *	in mm. This parameter can be empty; in this case, the text uses the total
 | 
				
			||||||
 | 
					 *	height of the name tag.
 | 
				
			||||||
 | 
					 * font: the path to a font for Write.scad.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					module bottle_clip(ru=13, rl=17.5, ht=26, width=2.5, name="", gap=90,
 | 
				
			||||||
 | 
							logo="thing-logos/stratum0-lowres.dxf", font="write/orbitron.dxf") {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						e=100;  // should be big enough, used for the outer boundary of the text/logo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						difference() {
 | 
				
			||||||
 | 
							rotate([0,0,-45]) union() {
 | 
				
			||||||
 | 
								// main cylinder
 | 
				
			||||||
 | 
								cylinder(r1=rl+width, r2=ru+width, h=ht);
 | 
				
			||||||
 | 
								// text and logo
 | 
				
			||||||
 | 
								if(logo == "") {
 | 
				
			||||||
 | 
									writecylinder(name, [0,0,3], rl+0.5, ht/13*7, h=ht/13*8, t=max(rl,ru),
 | 
				
			||||||
 | 
										font=font);
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									writecylinder(name, [0,0,0], rl+0.5, ht/13*7, h=ht/13*4, t=max(rl,ru),
 | 
				
			||||||
 | 
										font=font);
 | 
				
			||||||
 | 
									translate([0,0,ht*3/4-0.1])
 | 
				
			||||||
 | 
										rotate([90,0,0])
 | 
				
			||||||
 | 
										scale([ht/100,ht/100,1])
 | 
				
			||||||
 | 
										translate([-25,-25,0.5])
 | 
				
			||||||
 | 
										linear_extrude(height=max(ru,rl)*2)
 | 
				
			||||||
 | 
										import(logo);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							// inner cylinder which is substracted
 | 
				
			||||||
 | 
							translate([0,0,-1])
 | 
				
			||||||
 | 
								cylinder(r1=rl, r2=ru, h=ht+2);
 | 
				
			||||||
 | 
							// outer cylinder which is substracted, so the text and the logo end
 | 
				
			||||||
 | 
							// somewhere on the outside ;-)
 | 
				
			||||||
 | 
							difference () {
 | 
				
			||||||
 | 
								cylinder(r1=rl+e, r2=ru+e, h=ht);
 | 
				
			||||||
 | 
								translate([0,0,-1])
 | 
				
			||||||
 | 
									// Note: bottom edges of characters are hard to print when character
 | 
				
			||||||
 | 
									// depth is > 0.7
 | 
				
			||||||
 | 
									cylinder(r1=rl+width+0.7, r2=ru+width+0.7, h=ht+2);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// finally, substract an equilateral triangle as a gap so we can clip it to
 | 
				
			||||||
 | 
							// the bottle
 | 
				
			||||||
 | 
							gap_x=50*sin(45-gap/2);
 | 
				
			||||||
 | 
							gap_y=50*cos(45-gap/2);
 | 
				
			||||||
 | 
							translate([0,0,-1])
 | 
				
			||||||
 | 
								linear_extrude(height=50)
 | 
				
			||||||
 | 
								polygon(points=[[0,0], [gap_x, gap_y], [50,50], [gap_y, gap_x]]);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Creates one instance of a bottle clip name tag suitable for 0.33l longneck
 | 
				
			||||||
 | 
					 * bottles (like fritz cola, etc.). All parameters are passed to the module
 | 
				
			||||||
 | 
					 * bottle_clip(), see there for their documentation.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					module bottle_clip_longneck(name="", width=2.5, gap=90,
 | 
				
			||||||
 | 
							logo="thing-logos/stratum0-lowres.dxf", font="write/orbitron.dxf") {
 | 
				
			||||||
 | 
						bottle_clip(name=name, ru=13, rl=15, ht=26, width=width, logo=logo, gap=gap,
 | 
				
			||||||
 | 
							font=font);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * Creates one instance of a bottle clip name tag suitable for 0.33l DIN 6199
 | 
				
			||||||
 | 
					 * beer bottles (also known as "Steinie", "Stubbi", "Knolle", etc.). Because of
 | 
				
			||||||
 | 
					 * reasons, there is no logo, but all other parameters are passed to the module
 | 
				
			||||||
 | 
					 * bottle_clip(), see there for their documentation.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					module bottle_clip_steinie(name="", width=2.5, gap=90, font="write/orbitron.dxf") {
 | 
				
			||||||
 | 
						bottle_clip(name=name, ru=13, rl=17.5, ht=13, width=width, logo="", gap=gap,
 | 
				
			||||||
 | 
							font=font);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Create one instance of a bottle clip name tag suitable for 0.5l DIN 6198
 | 
				
			||||||
 | 
					 * bottle (also known as "Euroflasche" or "Euroform 2"). All parameters are
 | 
				
			||||||
 | 
					 * passed to the module bottle_clip(), see there for their documentation.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					module bottle_clip_euro2(name="", width=2.5, gap=90,
 | 
				
			||||||
 | 
					    logo="thing-logos/stratum0-lowres.dxf", font="write/orbitron.dxf") {
 | 
				
			||||||
 | 
					  bottle_clip(name=name, ru=13, rl=22.5, ht=26, width=width, logo=logo, gap=gap,
 | 
				
			||||||
 | 
					    font=font);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// vim: set noet ts=2 sw=2 tw=80:
 | 
				
			||||||
							
								
								
									
										1964
									
								
								app/openscad/thing-logos/fablab-cube2.dxf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1964
									
								
								app/openscad/thing-logos/fablab-cube2.dxf
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										2676
									
								
								app/openscad/thing-logos/fablab-cube2.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2676
									
								
								app/openscad/thing-logos/fablab-cube2.svg
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										378
									
								
								app/openscad/write/Write.scad
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										378
									
								
								app/openscad/write/Write.scad
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,378 @@
 | 
				
			|||||||
 | 
					/* 	Version 3
 | 
				
			||||||
 | 
						Added support for font selection (default is Letters.dxf)
 | 
				
			||||||
 | 
						Added WriteCube module
 | 
				
			||||||
 | 
						Added Rotate for text (rotates on the plane of the text)
 | 
				
			||||||
 | 
						Added writesphere
 | 
				
			||||||
 | 
						Added space=     (spacing between characters in char widths) def=1
 | 
				
			||||||
 | 
						Added writecylinder()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 By Harlan Martin
 | 
				
			||||||
 | 
					 harlan@sutlog.com
 | 
				
			||||||
 | 
					 January 2012
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 (The file TestWrite.scad gives More usage examples)
 | 
				
			||||||
 | 
					 (This module requires the file Letters.dxf to reside in the same folder)
 | 
				
			||||||
 | 
					 (The file Letters.dfx was created with inkscape..Each letter is in its own layer)
 | 
				
			||||||
 | 
					 (This module seperates each letter in the string and imports it from Letters.dfx)
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						pi=3.1415926535897932384626433832795028841971693993751058209;
 | 
				
			||||||
 | 
						pi2=pi*2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// These control the default values for write() writesphere() writecube()
 | 
				
			||||||
 | 
					// if the parameters are not included in the call. Feel free to set your own
 | 
				
			||||||
 | 
					// defaults.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//default settings
 | 
				
			||||||
 | 
						center=false;
 | 
				
			||||||
 | 
						h = 4;			 //mm letter height
 | 
				
			||||||
 | 
						t = 1; 			//mm letter thickness
 | 
				
			||||||
 | 
						space =1; 			//extra space between characters in (character widths)
 | 
				
			||||||
 | 
						rotate=0;			// text rotation (clockwise)
 | 
				
			||||||
 | 
						font = "Letters.dxf";	//default for aditional fonts
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// write cube defaults
 | 
				
			||||||
 | 
						face = "front";	 // default face (top,bottom,left,right,back,front)
 | 
				
			||||||
 | 
						up =0;		 //mm up from center on face of cube
 | 
				
			||||||
 | 
						down=0;
 | 
				
			||||||
 | 
						right =0;		 //mm left from center on face of cube
 | 
				
			||||||
 | 
						left=0;		
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// write sphere defaults
 | 
				
			||||||
 | 
						rounded=false;	 //default for rounded letters on writesphere
 | 
				
			||||||
 | 
						north=0; 		// intial text position (I suggest leave these 0 defaults)
 | 
				
			||||||
 | 
						south=0;
 | 
				
			||||||
 | 
						east=0;
 | 
				
			||||||
 | 
						west=0;
 | 
				
			||||||
 | 
						spin=0;
 | 
				
			||||||
 | 
					// writecylinder defaults
 | 
				
			||||||
 | 
						middle=0;     //(mm toward middle of circle)
 | 
				
			||||||
 | 
						ccw=false;   //write on top or bottom in a ccw direction
 | 
				
			||||||
 | 
					 	r1=0; 	//(not implimented yet)
 | 
				
			||||||
 | 
						r2=0;	 	//(not implimented yet)
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Contact me if your interested in how to make your own font files
 | 
				
			||||||
 | 
					// Its tedious and time consuming, but not very hard
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module writecylinder(text,where,radius,height){
 | 
				
			||||||
 | 
						wid=(.125* h *5.5 * space);
 | 
				
			||||||
 | 
						widall=wid*(len(text)-1)/2; 
 | 
				
			||||||
 | 
						//angle that measures width of letters on sphere
 | 
				
			||||||
 | 
						function NAngle(radius)=(wid/(pi2*radius))*360;
 | 
				
			||||||
 | 
						//angle of half width of text
 | 
				
			||||||
 | 
						function mmangle(radius)=(widall/(pi2*radius)*360);
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						if ((face=="top")||(face=="bottom") ){
 | 
				
			||||||
 | 
							if (face=="top" ){
 | 
				
			||||||
 | 
								if (center==true){
 | 
				
			||||||
 | 
									writecircle(text,where+[0,0,height/2],radius-h,rotate=rotate,font=font,h=h,t=t,
 | 
				
			||||||
 | 
									space=space,east=east,west=west,middle=middle,ccw=ccw);
 | 
				
			||||||
 | 
								}else{
 | 
				
			||||||
 | 
									writecircle(text,where+[0,0,height],radius-h,rotate=rotate,font=font,h=h,t=t,
 | 
				
			||||||
 | 
									space=space,east=east,west=west,middle=middle,ccw=ccw);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}else{
 | 
				
			||||||
 | 
								rotate(180,[1,0,0])
 | 
				
			||||||
 | 
								if (center==true){
 | 
				
			||||||
 | 
									writecircle(text,where+[0,0,height/2],radius-h,rotate=rotate,font=font,h=h,t=t,
 | 
				
			||||||
 | 
									space=space,east=east,west=west,middle=middle,ccw=ccw);
 | 
				
			||||||
 | 
								}else{
 | 
				
			||||||
 | 
									writecircle(text,where+[0,0,0],radius-h,rotate=rotate,font=font,h=h,t=t,
 | 
				
			||||||
 | 
									space=space,east=east,west=west,middle=middle,ccw=ccw);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						}else{
 | 
				
			||||||
 | 
					//		if (radius>0){
 | 
				
			||||||
 | 
								if (center==true)  {
 | 
				
			||||||
 | 
									rotate(-mmangle(radius)*(1-abs(rotate)/90),[0,0,1])
 | 
				
			||||||
 | 
									translate(where)
 | 
				
			||||||
 | 
									writethecylinder(text,where,radius,height,r1=radius,r2=radius,h=h,
 | 
				
			||||||
 | 
										rotate=rotate,t=t,font=font,face=face,up=up,down=down,
 | 
				
			||||||
 | 
										east=east,west=west,center=center,space=space,rounded=rounded);
 | 
				
			||||||
 | 
								} else{
 | 
				
			||||||
 | 
									rotate(-mmangle(radius)*(1-abs(rotate)/90),[0,0,1])
 | 
				
			||||||
 | 
									translate(where+[0,0,height/2])
 | 
				
			||||||
 | 
										writethecylinder(text,where,radius,height,r1=radius,r2=radius,h=h,
 | 
				
			||||||
 | 
										rotate=rotate,t=t,font=font,face=face,up=up,down=down,
 | 
				
			||||||
 | 
										east=east,west=west,center=center,space=space,rounded=rounded);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					// the remarked out code is for cone shaped cylinders (not complete)
 | 
				
			||||||
 | 
					//		}else{
 | 
				
			||||||
 | 
					//			if (center==true)  {
 | 
				
			||||||
 | 
					//				rotate(-mmangle(radius)*(1-abs(rotate)/90),[0,0,1])
 | 
				
			||||||
 | 
					//				translate(where)
 | 
				
			||||||
 | 
					//				writethecylinder(text,where,radius,height,r1=r1,r2=r2,h=h,
 | 
				
			||||||
 | 
					//					rotate=rotate,t=t,font=font,face=face,up=up,down=down,
 | 
				
			||||||
 | 
					//					east=east,west=west,center=center,space=space,rounded=rounded);
 | 
				
			||||||
 | 
					//			} else{
 | 
				
			||||||
 | 
					//				rotate(-mmangle(radius)*(1-abs(rotate)/90),[0,0,1])
 | 
				
			||||||
 | 
					//				translate(where+[0,0,height/2])
 | 
				
			||||||
 | 
					//					writethecylinder(text,where,radius,height,r1=r1,r2=r2,h=h,
 | 
				
			||||||
 | 
					//					rotate=rotate,t=t,font=font,face=face,up=up,down=down,
 | 
				
			||||||
 | 
					//					east=east,west=west,center=center,space=space,rounded=rounded);
 | 
				
			||||||
 | 
					//			}
 | 
				
			||||||
 | 
					//		}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					module writecircle(text,where,radius){
 | 
				
			||||||
 | 
						wid=(.125* h *5.5 * space);
 | 
				
			||||||
 | 
						widall=wid*(len(text)-1)/2;
 | 
				
			||||||
 | 
						//angle that measures width of letters on sphere
 | 
				
			||||||
 | 
						function NAngle(radius)=(wid/(pi2*radius))*360;
 | 
				
			||||||
 | 
						//angle of half width of text
 | 
				
			||||||
 | 
						function mmangle(radius)=(widall/(pi2*radius)*360);	
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						if (ccw==true){
 | 
				
			||||||
 | 
							rotate(-rotate+east-west,[0,0,1]){
 | 
				
			||||||
 | 
								rotate(-mmangle(radius-middle),[0,0,1]){
 | 
				
			||||||
 | 
								translate(where)
 | 
				
			||||||
 | 
									for (r=[0:len(text)-1]){
 | 
				
			||||||
 | 
										rotate(-90+r*NAngle(radius-middle),[0,0,1]) // bottom out=-270+r 
 | 
				
			||||||
 | 
										translate([radius-middle,0,0])
 | 
				
			||||||
 | 
										//rotate(90,[1,0,0])
 | 
				
			||||||
 | 
										//rotate(90,[0,1,0])
 | 
				
			||||||
 | 
										rotate(-270,[0,0,1])  // flip text (botom out = -270)
 | 
				
			||||||
 | 
										write(text[r],center=true,h=h,t=t,font=font);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}else{
 | 
				
			||||||
 | 
							rotate(-rotate-east+west,[0,0,1]){
 | 
				
			||||||
 | 
								rotate(mmangle(radius-middle),[0,0,1]){
 | 
				
			||||||
 | 
								translate(where)
 | 
				
			||||||
 | 
									for (r=[0:len(text)-1]){
 | 
				
			||||||
 | 
										rotate(90-r*NAngle(radius-middle),[0,0,1]) // bottom out=-270+r 
 | 
				
			||||||
 | 
										translate([radius-middle,0,0])
 | 
				
			||||||
 | 
										//rotate(90,[1,0,0])
 | 
				
			||||||
 | 
										//rotate(90,[0,1,0])
 | 
				
			||||||
 | 
										rotate(270,[0,0,1])  // flip text (botom out = -270)
 | 
				
			||||||
 | 
										write(text[r],center=true,h=h,t=t,font=font);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}		
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					module writethecylinder(text,where,radius,height,r1,r2){
 | 
				
			||||||
 | 
						wid=(.125* h *5.5 * space);
 | 
				
			||||||
 | 
						widall=wid*(len(text)-1)/2; 
 | 
				
			||||||
 | 
						//angle that measures width of letters on sphere
 | 
				
			||||||
 | 
						function NAngle(radius)=(wid/(pi2*radius))*360*(1-abs(rotate)/90);
 | 
				
			||||||
 | 
						//angle of half width of text
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						function mmangle(radius)=(widall/(pi2*radius)*360);
 | 
				
			||||||
 | 
								translate([0,0,up-down])
 | 
				
			||||||
 | 
								rotate(east-west,[0,0,1])
 | 
				
			||||||
 | 
								for (r=[0:len(text)-1]){
 | 
				
			||||||
 | 
									rotate(-90+(r*NAngle(radius)),[0,0,1])
 | 
				
			||||||
 | 
									translate([radius,0,-r*((rotate)/90*wid)+(len(text)-1)/2*((rotate)/90*wid)])
 | 
				
			||||||
 | 
									rotate(90,[1,0,0])
 | 
				
			||||||
 | 
									rotate(90,[0,1,0])
 | 
				
			||||||
 | 
									write(text[r],center=true,h=h,rotate=rotate,t=t,font=font);
 | 
				
			||||||
 | 
							//echo("zloc=",height/2-r*((rotate)/90*wid)+(len(text)-1)/2*((rotate)/90*wid));
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module writesphere(text,where,radius){
 | 
				
			||||||
 | 
						wid=(.125* h *5.5 * space);
 | 
				
			||||||
 | 
						widall=wid*(len(text)-1)/2;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						echo("-----------------",widall,wid,mmangle(radius));
 | 
				
			||||||
 | 
						//angle that measures width of letters on sphere
 | 
				
			||||||
 | 
						function NAngle(radius)=(wid/(pi2*radius))*360;
 | 
				
			||||||
 | 
						//angle of half width of text
 | 
				
			||||||
 | 
						function mmangle(radius)=(widall/(pi2*radius)*360);	
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						rotate(east-west,[0,0,1]){
 | 
				
			||||||
 | 
						rotate(south-north,[1,0,0]){
 | 
				
			||||||
 | 
						rotate(spin,[0,1,0]){
 | 
				
			||||||
 | 
						rotate(-mmangle(radius),[0,0,1]){
 | 
				
			||||||
 | 
							if ( rounded== false ){
 | 
				
			||||||
 | 
								translate(where)
 | 
				
			||||||
 | 
								for (r=[0:len(text)-1]){
 | 
				
			||||||
 | 
									rotate(-90+r*NAngle(radius),[0,0,1])
 | 
				
			||||||
 | 
									translate([radius,0,0])
 | 
				
			||||||
 | 
									rotate(90,[1,0,0])
 | 
				
			||||||
 | 
									rotate(90,[0,1,0])
 | 
				
			||||||
 | 
									write(text[r],center=true,h=h,rotate=rotate,t=t,font=font);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}else{
 | 
				
			||||||
 | 
								difference(){
 | 
				
			||||||
 | 
									translate(where)
 | 
				
			||||||
 | 
									for (r=[0:len(text)-1]){
 | 
				
			||||||
 | 
										rotate(-90+r*NAngle(radius),[0,0,1])
 | 
				
			||||||
 | 
										translate([radius,0,0])
 | 
				
			||||||
 | 
										rotate(90,[1,0,0])
 | 
				
			||||||
 | 
										rotate(90,[0,1,0])
 | 
				
			||||||
 | 
										write(text[r],center=true,h=h,rotate=rotate,t=t*2+h,font=font);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									difference(){ //rounded outside
 | 
				
			||||||
 | 
										sphere(radius+(t*2+h)*2);
 | 
				
			||||||
 | 
										sphere(radius+t/2);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									sphere(radius-t/2); // rounded inside for indented text
 | 
				
			||||||
 | 
								} 
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}}}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module writecube(text,where,size){
 | 
				
			||||||
 | 
						if (str(size)[0] != "["){  
 | 
				
			||||||
 | 
							// its a square cube (size was not a matrix so make it one)
 | 
				
			||||||
 | 
							writethecube(text,where,[size,size,size],h=h,rotate=rotate,space=space,
 | 
				
			||||||
 | 
							t=t,font=font,face=face,up=up,down=down,right=right,left=left);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						}else{
 | 
				
			||||||
 | 
							// its not square
 | 
				
			||||||
 | 
							writethecube(text,where,size,h=h,rotate=rotate,space=space,
 | 
				
			||||||
 | 
							t=t,font=font,face=face,up=up,down=down,right=right,left=left);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					// I split the writecube module into 2 pieces.. easier to add features later
 | 
				
			||||||
 | 
					module writethecube(text,where,size){
 | 
				
			||||||
 | 
							if (face=="front") {
 | 
				
			||||||
 | 
								translate([where[0]+right-left,where[1]-size[1]/2,where[2]+up-down])
 | 
				
			||||||
 | 
								rotate(90,[1,0,0])
 | 
				
			||||||
 | 
								write(text,center=true,h=h,rotate=rotate,t=t,font=font);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (face=="back") {
 | 
				
			||||||
 | 
								translate([where[0]+right-left,where[1]+size[1]/2,where[2]+up-down])
 | 
				
			||||||
 | 
								rotate(90,[1,0,0])   // rotate around the x axis
 | 
				
			||||||
 | 
								rotate(180,[0,1,0])  // rotate around the y axis (z before rotation)
 | 
				
			||||||
 | 
								write(text,center=true,h=h,rotate=rotate,t=t,font=font);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (face=="left") {
 | 
				
			||||||
 | 
								translate([where[0]-size[0]/2,where[1]-right+left,where[2]+up-down ])
 | 
				
			||||||
 | 
								rotate(90,[1,0,0])   // rotate around the x axis
 | 
				
			||||||
 | 
								rotate(90,[0,-1,0])  // rotate around the y axis  (z before rotation)
 | 
				
			||||||
 | 
								write(text,center=true,h=h,rotate=rotate,t=t,font=font);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (face=="right") {
 | 
				
			||||||
 | 
								translate([where[0]+size[0]/2,where[1]+right-left,where[2] +up-down])
 | 
				
			||||||
 | 
								rotate(90,[1,0,0])   // rotate around the x axis
 | 
				
			||||||
 | 
								rotate(90,[0,1,0])  // rotate around the y axis  (z before rotation)
 | 
				
			||||||
 | 
								write(text,center=true,h=h,rotate=rotate,t=t,font=font);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (face=="top") {
 | 
				
			||||||
 | 
								translate([where[0]+right-left,where[1]+up-down,where[2]+size[2]/2 ])
 | 
				
			||||||
 | 
								write(text,center=true,h=h,rotate=rotate,t=t,font=font);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if (face=="bottom") {
 | 
				
			||||||
 | 
								translate([where[0]+right-left,where[1]-up+down,where[2]-size[2]/2 ])
 | 
				
			||||||
 | 
								rotate(180,[1,0,0])
 | 
				
			||||||
 | 
								write(text,center=true,h=h,rotate=rotate,t=t,font=font);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module write(word){
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						echo (h);
 | 
				
			||||||
 | 
						echo (word);
 | 
				
			||||||
 | 
						echo ("There are " ,len(word) ," letters in this string");
 | 
				
			||||||
 | 
					//	echo ("The second letter is ",word[1]);
 | 
				
			||||||
 | 
					//	echo (str(word[0],"_"));
 | 
				
			||||||
 | 
					rotate(rotate,[0,0,-1]){
 | 
				
			||||||
 | 
						for (r = [0:len(word)]){   // count off each character
 | 
				
			||||||
 | 
							// if the letter is lower case, add an underscore to the end for file lookup
 | 
				
			||||||
 | 
							if ((word[r] == "a" ) || (word[r]== "b")  || (word[r]== "c") 
 | 
				
			||||||
 | 
						 	  || (word[r]== "d") || (word[r]== "e") || (word[r]== "f") 
 | 
				
			||||||
 | 
						 	  || (word[r]== "g") || (word[r]== "h")  || (word[r]== "i") 
 | 
				
			||||||
 | 
					       	  	  || (word[r]== "j") || (word[r]== "k") || (word[r]== "l")
 | 
				
			||||||
 | 
					       	 	  || (word[r]== "m") || (word[r]== "n") || (word[r]== "o") 
 | 
				
			||||||
 | 
					       	 	  || (word[r]== "p") || (word[r]== "q") || (word[r]== "r") 
 | 
				
			||||||
 | 
						 	  || (word[r]== "s") || (word[r]== "t") || (word[r]== "u") 
 | 
				
			||||||
 | 
					       	 	  || (word[r]== "v") || (word[r]== "w") || (word[r]== "x") 
 | 
				
			||||||
 | 
					       	 	  || (word[r]== "y" )|| (word[r]== "z")){
 | 
				
			||||||
 | 
								if (center == true)  {
 | 
				
			||||||
 | 
									translate([0,-h/2,0]){
 | 
				
			||||||
 | 
										scale([.125*h,.125*h,t]){	
 | 
				
			||||||
 | 
											translate([ (-len(word)*5.5*space/2) + (r*5.5*space),0,0])
 | 
				
			||||||
 | 
											linear_extrude(height=1,convexity=10,center=true){
 | 
				
			||||||
 | 
												import(file = font,layer=str(word[r],"_"));
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}else{
 | 
				
			||||||
 | 
									translate([0,0,t/2]){
 | 
				
			||||||
 | 
										scale([.125*h,.125*h,t]){	
 | 
				
			||||||
 | 
											translate([r*5.5*space,0,0])
 | 
				
			||||||
 | 
											linear_extrude(height=1,convexity=10,center=true){
 | 
				
			||||||
 | 
												import(file = font,layer=str(word[r],"_"));
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							}else{
 | 
				
			||||||
 | 
								if (center == true)  {
 | 
				
			||||||
 | 
									translate([0,-h/2,0]){
 | 
				
			||||||
 | 
										scale([.125*h,.125*h,t]){
 | 
				
			||||||
 | 
											translate([ (-len(word)*5.5*space/2) + (r*5.5*space),0,0])
 | 
				
			||||||
 | 
											linear_extrude(height=1,convexity=10,center=true){
 | 
				
			||||||
 | 
												import(file = font,layer=str(word[r]));
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}else{
 | 
				
			||||||
 | 
									translate([0,0,t/2]){
 | 
				
			||||||
 | 
										scale([.125*h,.125*h,t]){
 | 
				
			||||||
 | 
											translate([r*5.5*space,0,0])
 | 
				
			||||||
 | 
											linear_extrude(height=1,convexity=10,center=true){
 | 
				
			||||||
 | 
												import(file = font,layer=str(word[r]));
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*writecylinder test
 | 
				
			||||||
 | 
					translate([0,0,0])
 | 
				
			||||||
 | 
					%cylinder(r=20,h=40,center=true);
 | 
				
			||||||
 | 
					color([1,0,0])
 | 
				
			||||||
 | 
					writecylinder("rotate=90",[0,0,0],20,40,center=true,down=0,rotate=90);
 | 
				
			||||||
 | 
					writecylinder("rotate = 30,east = 90",[0,0,0],20,40,center=true,down=0,rotate=30,east=90);
 | 
				
			||||||
 | 
					writecylinder("ccw = true",[0,0,0],20,40,center=true,down=0,face="top",ccw=true);
 | 
				
			||||||
 | 
					writecylinder("middle = 8",[0,0,0],20,40,h=3,center=true,down=0,face="top",middle=8);
 | 
				
			||||||
 | 
					writecylinder("face = top",[0,0,0],20,40,center=true,down=0,face="top");
 | 
				
			||||||
 | 
					writecylinder("east=90",[0,0,0],20,40,h=3,center=true,down=0,face="top",east=90);
 | 
				
			||||||
 | 
					writecylinder("west=90",[0,0,0],20,40,h=3,center=true,down=0,face="top",ccw=true,west=90);
 | 
				
			||||||
 | 
					writecylinder("face = bottom",[0,0,0],20,40,center=true,down=0,face="bottom"); 
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					/*writesphere test
 | 
				
			||||||
 | 
					sphere(20);
 | 
				
			||||||
 | 
					color([1,0,0])
 | 
				
			||||||
 | 
					writesphere("Hello World",[0,0,0],20,t=1,h=6);
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					/* writecube test
 | 
				
			||||||
 | 
					translate([30,30,30])
 | 
				
			||||||
 | 
					cube([10,15,30],center=true);
 | 
				
			||||||
 | 
					write("hello",center=true,rotate =30);
 | 
				
			||||||
 | 
					color([1,0,0])
 | 
				
			||||||
 | 
					writecube( "front",[30,30,30],[10,15,30],h=5,rotate=-90);
 | 
				
			||||||
 | 
					color([0,1,0])
 | 
				
			||||||
 | 
					writecube( "back",[30,30,30],size=[10,15,30],h=5,face="back",rotate=90,t=4);
 | 
				
			||||||
 | 
					color([0,0,1])
 | 
				
			||||||
 | 
					writecube( "left",[30,30,30],[10,15,30],h=5,face="left",up=5);
 | 
				
			||||||
 | 
					color([1,1,0])
 | 
				
			||||||
 | 
					writecube( "right",where=[30,30,30],size=[10,15,30],h=5,face="right",rotate=55);
 | 
				
			||||||
 | 
					color([1,0,1])
 | 
				
			||||||
 | 
					writecube( "top",where=[30,30,30],size=[10,15,30],h=5,face="top");
 | 
				
			||||||
 | 
					color([1,1,1])
 | 
				
			||||||
 | 
					writecube( "bttm",where=[30,30,30],size=[10,15,30],h=5,face="bottom",rotate=90);
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										16730
									
								
								app/openscad/write/orbitron.dxf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16730
									
								
								app/openscad/write/orbitron.dxf
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										81
									
								
								app/static/logo.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								app/static/logo.svg
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,81 @@
 | 
				
			|||||||
 | 
					<?xml version="1.0" encoding="utf-8"?>
 | 
				
			||||||
 | 
					<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
 | 
				
			||||||
 | 
					<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
 | 
				
			||||||
 | 
						 viewBox="0 0 639 186" style="enable-background:new 0 0 639 186;" xml:space="preserve">
 | 
				
			||||||
 | 
					<style type="text/css">
 | 
				
			||||||
 | 
						.st0{display:none;stroke:#000000;stroke-miterlimit:10;}
 | 
				
			||||||
 | 
						.st1{fill:#939393;}
 | 
				
			||||||
 | 
						.st2{fill:#D13F34;}
 | 
				
			||||||
 | 
						.st3{fill:#16A3C4;}
 | 
				
			||||||
 | 
						.st4{fill:none;stroke:#010101;}
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
 | 
					<rect class="st0" width="639" height="186"/>
 | 
				
			||||||
 | 
					<g id="g3" transform="translate(-18.822 2.708864)">
 | 
				
			||||||
 | 
						<path id="path5" class="st1" d="M91.2,157.7v-20.8c0.7-0.3,1.5-0.6,2.2-1c9.9-5.8,11-22.4,2.3-37.1C87.1,84.1,72,77,62.1,82.9
 | 
				
			||||||
 | 
							c-9.9,5.8-10.9,22.4-2.3,37.1c1.4,2.4,3,4.5,4.6,6.5v15.4l-21.4-12.2V53.1l-7.5-4.9C28.8,60.5,24.9,74.8,24.9,90
 | 
				
			||||||
 | 
							c0,47.1,37.4,85.5,84.2,87.1l0-9L91.2,157.7z"/>
 | 
				
			||||||
 | 
						<path id="path7" class="st2" d="M66.4,36l13.1,7.7c-0.3,2.1-0.3,4.5-0.3,5.3c0.1,11.5,15.7,20.2,32.7,20.1s29.1-10.5,29-20.6
 | 
				
			||||||
 | 
							c-0.1-11.5-11.2-20.5-28.1-21c-5.7-0.2-11.3,1-13.8,1.5l-9.5-6.1L112,10l66.7,38.8l7.7-4.2c-7.4-12.1-17.8-22.6-30.9-30.2
 | 
				
			||||||
 | 
							C114.6-9.1,62.7,4.2,38,43.9l7.6,4.8L66.4,36L66.4,36z"/>
 | 
				
			||||||
 | 
						<path id="path9" class="st3" d="M181,78.2l-14.2,7.4c-0.5-0.1-3.7-3-4.4-3.4c-10-5.6-24.8,1.8-33.1,16.6
 | 
				
			||||||
 | 
							c-8.3,14.8-7.6,31.8,2.5,37.4c10,5.6,25-1.1,33.3-16c1.3-2.4,3.1-7.9,3.9-10.4l12.1-7l-0.1,26.5l-66.6,38.9l0,8.8
 | 
				
			||||||
 | 
							c14.2-0.4,28.4-4.3,41.5-11.9c40.7-23.8,54.9-75.5,32.6-116.6l-7.7,4.2V78.2L181,78.2z"/>
 | 
				
			||||||
 | 
					</g>
 | 
				
			||||||
 | 
					<path id="path11" class="st4" d="M119.6,176.5"/>
 | 
				
			||||||
 | 
					<g>
 | 
				
			||||||
 | 
						<path class="st1" d="M252.5,28.3h-31.3v21.8H250v16.2h-28.8v34.5h-20V12h51.3V28.3z"/>
 | 
				
			||||||
 | 
						<path class="st1" d="M340.4,100.8h-21.8l-6.3-19.8h-31.6l-6.3,19.8h-21.7L285.1,12h23.7L340.4,100.8z M307.7,65.7l-9.5-29.9
 | 
				
			||||||
 | 
							c-0.7-2.2-1.2-4.9-1.5-8h-0.5c-0.2,2.6-0.7,5.2-1.5,7.7l-9.7,30.1H307.7z"/>
 | 
				
			||||||
 | 
						<path class="st1" d="M349.5,100.8V12h32.3c9.9,0,17.5,1.8,22.9,5.5c5.3,3.6,8,8.8,8,15.4c0,4.8-1.6,9-4.9,12.6
 | 
				
			||||||
 | 
							c-3.2,3.6-7.4,6.1-12.4,7.5v0.2c6.3,0.8,11.4,3.1,15.1,7c3.8,3.9,5.7,8.6,5.7,14.2c0,8.1-2.9,14.6-8.7,19.4s-13.8,7.2-23.8,7.2
 | 
				
			||||||
 | 
							H349.5z M369.5,26.7v21.1h8.8c4.1,0,7.4-1,9.8-3c2.4-2,3.6-4.8,3.6-8.3c0-6.5-4.9-9.8-14.6-9.8H369.5z M369.5,62.7v23.4h10.8
 | 
				
			||||||
 | 
							c4.6,0,8.2-1.1,10.9-3.2c2.6-2.1,3.9-5.1,3.9-8.8c0-3.6-1.3-6.3-3.9-8.4c-2.6-2-6.2-3-10.8-3H369.5z"/>
 | 
				
			||||||
 | 
						<path class="st1" d="M478.4,100.8h-46.1V12h10.4v79.4h35.7V100.8z"/>
 | 
				
			||||||
 | 
						<path class="st1" d="M566.4,100.8h-11.5l-9.4-24.9h-37.7l-8.9,24.9h-11.6L521.4,12h10.8L566.4,100.8z M542.1,66.6l-13.9-37.8
 | 
				
			||||||
 | 
							c-0.5-1.2-0.9-3.2-1.4-5.9h-0.2c-0.4,2.5-0.9,4.5-1.4,5.9l-13.8,37.8H542.1z"/>
 | 
				
			||||||
 | 
						<path class="st1" d="M577.5,100.8V12h25.3c7.7,0,13.8,1.9,18.3,5.6c4.5,3.8,6.8,8.7,6.8,14.7c0,5-1.4,9.4-4.1,13.1
 | 
				
			||||||
 | 
							c-2.7,3.7-6.5,6.4-11.3,7.9v0.2c6,0.7,10.8,3,14.4,6.8c3.6,3.8,5.4,8.8,5.4,14.9c0,7.6-2.7,13.8-8.2,18.5
 | 
				
			||||||
 | 
							c-5.5,4.7-12.3,7.1-20.6,7.1H577.5z M587.9,21.4v28.7h10.7c5.7,0,10.2-1.4,13.4-4.1c3.3-2.7,4.9-6.6,4.9-11.6
 | 
				
			||||||
 | 
							c0-8.6-5.7-12.9-17-12.9H587.9z M587.9,59.4v32H602c6.1,0,10.8-1.4,14.2-4.3c3.4-2.9,5-6.9,5-11.9c0-10.5-7.1-15.7-21.4-15.7H587.9
 | 
				
			||||||
 | 
							z"/>
 | 
				
			||||||
 | 
					</g>
 | 
				
			||||||
 | 
					<g>
 | 
				
			||||||
 | 
						<path class="st2" d="M227.7,176.5h-5.3v-5.1h-0.1c-2.3,3.9-5.7,5.9-10.1,5.9c-3.3,0-5.8-0.9-7.7-2.6c-1.8-1.7-2.8-4-2.8-6.9
 | 
				
			||||||
 | 
							c0-6.1,3.6-9.7,10.8-10.7l9.8-1.4c0-5.6-2.3-8.4-6.8-8.4c-4,0-7.5,1.3-10.7,4V146c3.2-2.1,6.9-3.1,11.2-3.1
 | 
				
			||||||
 | 
							c7.7,0,11.6,4.1,11.6,12.2V176.5z M222.4,159.9l-7.9,1.1c-2.4,0.3-4.3,0.9-5.5,1.8c-1.2,0.9-1.9,2.4-1.9,4.6c0,1.6,0.6,2.9,1.7,3.9
 | 
				
			||||||
 | 
							c1.1,1,2.7,1.5,4.6,1.5c2.6,0,4.8-0.9,6.5-2.7c1.7-1.8,2.5-4.1,2.5-6.9V159.9z"/>
 | 
				
			||||||
 | 
						<path class="st2" d="M242.8,176.5h-5.3v-48.6h5.3V176.5z"/>
 | 
				
			||||||
 | 
						<path class="st2" d="M268.7,176.2c-1.2,0.7-2.9,1-4.9,1c-5.8,0-8.6-3.2-8.6-9.6v-19.4h-5.6v-4.5h5.6v-8l5.3-1.7v9.7h8.3v4.5h-8.3
 | 
				
			||||||
 | 
							v18.5c0,2.2,0.4,3.8,1.1,4.7c0.7,0.9,2,1.4,3.7,1.4c1.3,0,2.5-0.4,3.4-1.1V176.2z"/>
 | 
				
			||||||
 | 
						<path class="st2" d="M322.3,176.5h-5.3v-18.9c0-3.6-0.6-6.3-1.7-7.9c-1.1-1.6-3-2.4-5.7-2.4c-2.2,0-4.2,1-5.7,3.1
 | 
				
			||||||
 | 
							c-1.6,2.1-2.4,4.5-2.4,7.4v18.7h-5.3V157c0-6.5-2.5-9.7-7.5-9.7c-2.3,0-4.2,1-5.7,2.9c-1.5,1.9-2.2,4.5-2.2,7.6v18.7h-5.3v-32.8
 | 
				
			||||||
 | 
							h5.3v5.2h0.1c2.3-4,5.7-6,10.2-6c2.2,0,4.2,0.6,5.9,1.9c1.7,1.3,2.8,2.9,3.4,4.9c2.4-4.5,6.1-6.8,10.9-6.8
 | 
				
			||||||
 | 
							c7.2,0,10.8,4.5,10.8,13.4V176.5z"/>
 | 
				
			||||||
 | 
						<path class="st2" d="M358.8,176.5h-5.3v-5.2h-0.1c-2.2,4-5.6,6-10.1,6c-7.8,0-11.7-4.7-11.7-14v-19.6h5.2v18.8
 | 
				
			||||||
 | 
							c0,6.9,2.7,10.4,8,10.4c2.6,0,4.7-0.9,6.3-2.8c1.7-1.9,2.5-4.4,2.5-7.4v-18.9h5.3V176.5z M339.3,137.4c-0.9,0-1.7-0.3-2.3-0.9
 | 
				
			||||||
 | 
							c-0.6-0.6-0.9-1.4-0.9-2.2c0-0.9,0.3-1.6,0.9-2.2c0.6-0.6,1.4-0.9,2.2-0.9c0.9,0,1.6,0.3,2.3,0.9c0.6,0.6,1,1.4,1,2.2
 | 
				
			||||||
 | 
							c0,0.9-0.3,1.6-0.9,2.2C340.9,137.1,340.2,137.4,339.3,137.4z M351.6,137.4c-0.9,0-1.6-0.3-2.2-0.9c-0.6-0.6-0.9-1.4-0.9-2.3
 | 
				
			||||||
 | 
							c0-0.9,0.3-1.6,0.9-2.2c0.6-0.6,1.3-0.9,2.2-0.9c0.9,0,1.7,0.3,2.3,0.9s0.9,1.4,0.9,2.2c0,0.9-0.3,1.6-0.9,2.2
 | 
				
			||||||
 | 
							C353.3,137.1,352.5,137.4,351.6,137.4z"/>
 | 
				
			||||||
 | 
						<path class="st2" d="M396.7,176.5h-5.3v-18.9c0-6.8-2.5-10.3-7.6-10.3c-2.6,0-4.7,1-6.5,3c-1.8,2-2.6,4.5-2.6,7.6v18.6h-5.3v-48.6
 | 
				
			||||||
 | 
							h5.3v21.2h0.1c2.5-4.1,6.1-6.2,10.8-6.2c7.4,0,11.1,4.5,11.1,13.4V176.5z"/>
 | 
				
			||||||
 | 
						<path class="st2" d="M411.9,176.5h-5.3v-48.6h5.3V176.5z"/>
 | 
				
			||||||
 | 
						<path class="st2" d="M438.7,132.5c-1-0.6-2.2-0.9-3.5-0.9c-3.7,0-5.5,2.3-5.5,7v5.1h7.7v4.5h-7.7v28.3h-5.2v-28.3h-5.6v-4.5h5.6
 | 
				
			||||||
 | 
							v-5.3c0-3.4,1-6.2,3-8.2c2-2,4.5-3,7.4-3c1.6,0,2.9,0.2,3.8,0.6V132.5z"/>
 | 
				
			||||||
 | 
						<path class="st2" d="M460.2,149c-0.9-0.7-2.2-1.1-4-1.1c-2.2,0-4.1,1.1-5.6,3.2s-2.3,5-2.3,8.7v16.7h-5.3v-32.8h5.3v6.8h0.1
 | 
				
			||||||
 | 
							c0.7-2.3,1.9-4.1,3.4-5.4s3.3-1.9,5.2-1.9c1.4,0,2.4,0.1,3.1,0.4V149z"/>
 | 
				
			||||||
 | 
						<path class="st2" d="M489.4,176.5h-5.3v-5.1H484c-2.3,3.9-5.7,5.9-10.1,5.9c-3.3,0-5.8-0.9-7.7-2.6s-2.8-4-2.8-6.9
 | 
				
			||||||
 | 
							c0-6.1,3.6-9.7,10.8-10.7l9.8-1.4c0-5.6-2.3-8.4-6.8-8.4c-4,0-7.5,1.3-10.7,4V146c3.2-2.1,6.9-3.1,11.2-3.1
 | 
				
			||||||
 | 
							c7.7,0,11.6,4.1,11.6,12.2V176.5z M484.1,159.9l-7.9,1.1c-2.4,0.3-4.3,0.9-5.5,1.8c-1.2,0.9-1.9,2.4-1.9,4.6c0,1.6,0.6,2.9,1.7,3.9
 | 
				
			||||||
 | 
							c1.1,1,2.7,1.5,4.6,1.5c2.6,0,4.8-0.9,6.5-2.7c1.7-1.8,2.5-4.1,2.5-6.9V159.9z"/>
 | 
				
			||||||
 | 
						<path class="st2" d="M526.5,176.5h-5.3v-18.7c0-7-2.5-10.5-7.6-10.5c-2.6,0-4.8,1-6.5,3c-1.7,2-2.6,4.5-2.6,7.5v18.7h-5.3v-32.8
 | 
				
			||||||
 | 
							h5.3v5.5h0.1c2.5-4.1,6.1-6.2,10.8-6.2c3.6,0,6.3,1.2,8.2,3.5s2.9,5.7,2.9,10.1V176.5z"/>
 | 
				
			||||||
 | 
						<path class="st2" d="M563.7,176.5h-7.4l-14.5-15.8h-0.1v15.8h-5.3v-48.6h5.3v30.8h0.1l13.8-15h6.9l-15.2,15.8L563.7,176.5z"/>
 | 
				
			||||||
 | 
						<path class="st2" d="M594.2,161.4H571c0.1,3.7,1.1,6.5,2.9,8.5c1.9,2,4.5,3,7.8,3c3.7,0,7.1-1.2,10.2-3.7v4.9
 | 
				
			||||||
 | 
							c-2.9,2.1-6.7,3.1-11.4,3.1c-4.6,0-8.3-1.5-10.9-4.5c-2.7-3-4-7.2-4-12.6c0-5.1,1.4-9.3,4.3-12.5c2.9-3.2,6.5-4.8,10.8-4.8
 | 
				
			||||||
 | 
							s7.6,1.4,10,4.2c2.4,2.8,3.5,6.6,3.5,11.6V161.4z M588.8,156.9c0-3-0.8-5.4-2.2-7.1c-1.4-1.7-3.4-2.5-6-2.5c-2.5,0-4.6,0.9-6.3,2.7
 | 
				
			||||||
 | 
							c-1.7,1.8-2.8,4.1-3.2,7H588.8z"/>
 | 
				
			||||||
 | 
						<path class="st2" d="M629.4,176.5h-5.3v-18.7c0-7-2.5-10.5-7.6-10.5c-2.6,0-4.8,1-6.5,3c-1.7,2-2.6,4.5-2.6,7.5v18.7h-5.3v-32.8
 | 
				
			||||||
 | 
							h5.3v5.5h0.1c2.5-4.1,6.1-6.2,10.8-6.2c3.6,0,6.3,1.2,8.2,3.5c1.9,2.3,2.9,5.7,2.9,10.1V176.5z"/>
 | 
				
			||||||
 | 
					</g>
 | 
				
			||||||
 | 
					</svg>
 | 
				
			||||||
| 
		 After Width: | Height: | Size: 6.7 KiB  | 
							
								
								
									
										2675
									
								
								app/static/pico.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2675
									
								
								app/static/pico.css
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										22
									
								
								app/templates/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								app/templates/index.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html lang="de" xmlns="http://www.w3.org/1999/html" data-theme="dark">
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					    <title>FabLab Bottle Clip Generator</title>
 | 
				
			||||||
 | 
					    <link rel="stylesheet" href="{{ url_for('static', filename='pico.css') }}">
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					<main class="container">
 | 
				
			||||||
 | 
					    <center>
 | 
				
			||||||
 | 
					        <img src="{{ url_for('static', filename='logo.svg') }}" style="max-width: 350px; margin-bottom: 30px;">
 | 
				
			||||||
 | 
					        <h1>FabLab Bottle Clip Generator</h1>
 | 
				
			||||||
 | 
					        <p>Bitte gib deinen Namen in das Formular ein und drücke auf <b><i>Generieren</i></b>, um eine STL-Datei zu erhalten.</p>
 | 
				
			||||||
 | 
					        <form action="{{ url_for('generate_form') }}">
 | 
				
			||||||
 | 
					            <label for="name">Name:</label>
 | 
				
			||||||
 | 
					            <input type="text" id="name" name="name" style="text-align: center;" placeholder="Name">
 | 
				
			||||||
 | 
					            <input type="submit" value="Generieren">
 | 
				
			||||||
 | 
					        </form>
 | 
				
			||||||
 | 
					    </center>
 | 
				
			||||||
 | 
					</main>
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										7
									
								
								docker-compose.yml.example
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								docker-compose.yml.example
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
				
			|||||||
 | 
					version: '3'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					services:
 | 
				
			||||||
 | 
					  web:
 | 
				
			||||||
 | 
					    build: .
 | 
				
			||||||
 | 
					    ports:
 | 
				
			||||||
 | 
					      - 8000:8000
 | 
				
			||||||
							
								
								
									
										308
									
								
								poetry.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										308
									
								
								poetry.lock
									
									
									
										generated
									
									
									
										Normal file
									
								
							@@ -0,0 +1,308 @@
 | 
				
			|||||||
 | 
					# This file is automatically @generated by Poetry 1.5.0 and should not be changed by hand.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "aiofiles"
 | 
				
			||||||
 | 
					version = "23.1.0"
 | 
				
			||||||
 | 
					description = "File support for asyncio."
 | 
				
			||||||
 | 
					optional = false
 | 
				
			||||||
 | 
					python-versions = ">=3.7,<4.0"
 | 
				
			||||||
 | 
					files = [
 | 
				
			||||||
 | 
					    {file = "aiofiles-23.1.0-py3-none-any.whl", hash = "sha256:9312414ae06472eb6f1d163f555e466a23aed1c8f60c30cccf7121dba2e53eb2"},
 | 
				
			||||||
 | 
					    {file = "aiofiles-23.1.0.tar.gz", hash = "sha256:edd247df9a19e0db16534d4baaf536d6609a43e1de5401d7a4c1c148753a1635"},
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "blinker"
 | 
				
			||||||
 | 
					version = "1.5"
 | 
				
			||||||
 | 
					description = "Fast, simple object-to-object and broadcast signaling"
 | 
				
			||||||
 | 
					optional = false
 | 
				
			||||||
 | 
					python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
 | 
				
			||||||
 | 
					files = [
 | 
				
			||||||
 | 
					    {file = "blinker-1.5-py2.py3-none-any.whl", hash = "sha256:1eb563df6fdbc39eeddc177d953203f99f097e9bf0e2b8f9f3cf18b6ca425e36"},
 | 
				
			||||||
 | 
					    {file = "blinker-1.5.tar.gz", hash = "sha256:923e5e2f69c155f2cc42dafbbd70e16e3fde24d2d4aa2ab72fbe386238892462"},
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "click"
 | 
				
			||||||
 | 
					version = "8.1.3"
 | 
				
			||||||
 | 
					description = "Composable command line interface toolkit"
 | 
				
			||||||
 | 
					optional = false
 | 
				
			||||||
 | 
					python-versions = ">=3.7"
 | 
				
			||||||
 | 
					files = [
 | 
				
			||||||
 | 
					    {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"},
 | 
				
			||||||
 | 
					    {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"},
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[package.dependencies]
 | 
				
			||||||
 | 
					colorama = {version = "*", markers = "platform_system == \"Windows\""}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "colorama"
 | 
				
			||||||
 | 
					version = "0.4.6"
 | 
				
			||||||
 | 
					description = "Cross-platform colored terminal text."
 | 
				
			||||||
 | 
					optional = false
 | 
				
			||||||
 | 
					python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
 | 
				
			||||||
 | 
					files = [
 | 
				
			||||||
 | 
					    {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
 | 
				
			||||||
 | 
					    {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "h11"
 | 
				
			||||||
 | 
					version = "0.14.0"
 | 
				
			||||||
 | 
					description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1"
 | 
				
			||||||
 | 
					optional = false
 | 
				
			||||||
 | 
					python-versions = ">=3.7"
 | 
				
			||||||
 | 
					files = [
 | 
				
			||||||
 | 
					    {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"},
 | 
				
			||||||
 | 
					    {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"},
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "h2"
 | 
				
			||||||
 | 
					version = "4.1.0"
 | 
				
			||||||
 | 
					description = "HTTP/2 State-Machine based protocol implementation"
 | 
				
			||||||
 | 
					optional = false
 | 
				
			||||||
 | 
					python-versions = ">=3.6.1"
 | 
				
			||||||
 | 
					files = [
 | 
				
			||||||
 | 
					    {file = "h2-4.1.0-py3-none-any.whl", hash = "sha256:03a46bcf682256c95b5fd9e9a99c1323584c3eec6440d379b9903d709476bc6d"},
 | 
				
			||||||
 | 
					    {file = "h2-4.1.0.tar.gz", hash = "sha256:a83aca08fbe7aacb79fec788c9c0bac936343560ed9ec18b82a13a12c28d2abb"},
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[package.dependencies]
 | 
				
			||||||
 | 
					hpack = ">=4.0,<5"
 | 
				
			||||||
 | 
					hyperframe = ">=6.0,<7"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "hpack"
 | 
				
			||||||
 | 
					version = "4.0.0"
 | 
				
			||||||
 | 
					description = "Pure-Python HPACK header compression"
 | 
				
			||||||
 | 
					optional = false
 | 
				
			||||||
 | 
					python-versions = ">=3.6.1"
 | 
				
			||||||
 | 
					files = [
 | 
				
			||||||
 | 
					    {file = "hpack-4.0.0-py3-none-any.whl", hash = "sha256:84a076fad3dc9a9f8063ccb8041ef100867b1878b25ef0ee63847a5d53818a6c"},
 | 
				
			||||||
 | 
					    {file = "hpack-4.0.0.tar.gz", hash = "sha256:fc41de0c63e687ebffde81187a948221294896f6bdc0ae2312708df339430095"},
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "hypercorn"
 | 
				
			||||||
 | 
					version = "0.14.3"
 | 
				
			||||||
 | 
					description = "A ASGI Server based on Hyper libraries and inspired by Gunicorn"
 | 
				
			||||||
 | 
					optional = false
 | 
				
			||||||
 | 
					python-versions = ">=3.7"
 | 
				
			||||||
 | 
					files = [
 | 
				
			||||||
 | 
					    {file = "Hypercorn-0.14.3-py3-none-any.whl", hash = "sha256:7c491d5184f28ee960dcdc14ab45d14633ca79d72ddd13cf4fcb4cb854d679ab"},
 | 
				
			||||||
 | 
					    {file = "Hypercorn-0.14.3.tar.gz", hash = "sha256:4a87a0b7bbe9dc75fab06dbe4b301b9b90416e9866c23a377df21a969d6ab8dd"},
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[package.dependencies]
 | 
				
			||||||
 | 
					h11 = "*"
 | 
				
			||||||
 | 
					h2 = ">=3.1.0"
 | 
				
			||||||
 | 
					priority = "*"
 | 
				
			||||||
 | 
					toml = "*"
 | 
				
			||||||
 | 
					wsproto = ">=0.14.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[package.extras]
 | 
				
			||||||
 | 
					docs = ["pydata_sphinx_theme"]
 | 
				
			||||||
 | 
					h3 = ["aioquic (>=0.9.0,<1.0)"]
 | 
				
			||||||
 | 
					trio = ["trio (>=0.11.0)"]
 | 
				
			||||||
 | 
					uvloop = ["uvloop"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "hyperframe"
 | 
				
			||||||
 | 
					version = "6.0.1"
 | 
				
			||||||
 | 
					description = "HTTP/2 framing layer for Python"
 | 
				
			||||||
 | 
					optional = false
 | 
				
			||||||
 | 
					python-versions = ">=3.6.1"
 | 
				
			||||||
 | 
					files = [
 | 
				
			||||||
 | 
					    {file = "hyperframe-6.0.1-py3-none-any.whl", hash = "sha256:0ec6bafd80d8ad2195c4f03aacba3a8265e57bc4cff261e802bf39970ed02a15"},
 | 
				
			||||||
 | 
					    {file = "hyperframe-6.0.1.tar.gz", hash = "sha256:ae510046231dc8e9ecb1a6586f63d2347bf4c8905914aa84ba585ae85f28a914"},
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "itsdangerous"
 | 
				
			||||||
 | 
					version = "2.1.2"
 | 
				
			||||||
 | 
					description = "Safely pass data to untrusted environments and back."
 | 
				
			||||||
 | 
					optional = false
 | 
				
			||||||
 | 
					python-versions = ">=3.7"
 | 
				
			||||||
 | 
					files = [
 | 
				
			||||||
 | 
					    {file = "itsdangerous-2.1.2-py3-none-any.whl", hash = "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44"},
 | 
				
			||||||
 | 
					    {file = "itsdangerous-2.1.2.tar.gz", hash = "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a"},
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "jinja2"
 | 
				
			||||||
 | 
					version = "3.1.2"
 | 
				
			||||||
 | 
					description = "A very fast and expressive template engine."
 | 
				
			||||||
 | 
					optional = false
 | 
				
			||||||
 | 
					python-versions = ">=3.7"
 | 
				
			||||||
 | 
					files = [
 | 
				
			||||||
 | 
					    {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"},
 | 
				
			||||||
 | 
					    {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"},
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[package.dependencies]
 | 
				
			||||||
 | 
					MarkupSafe = ">=2.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[package.extras]
 | 
				
			||||||
 | 
					i18n = ["Babel (>=2.7)"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "markupsafe"
 | 
				
			||||||
 | 
					version = "2.1.2"
 | 
				
			||||||
 | 
					description = "Safely add untrusted strings to HTML/XML markup."
 | 
				
			||||||
 | 
					optional = false
 | 
				
			||||||
 | 
					python-versions = ">=3.7"
 | 
				
			||||||
 | 
					files = [
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:665a36ae6f8f20a4676b53224e33d456a6f5a72657d9c83c2aa00765072f31f7"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:340bea174e9761308703ae988e982005aedf427de816d1afe98147668cc03036"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22152d00bf4a9c7c83960521fc558f55a1adbc0631fbb00a9471e097b19d72e1"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28057e985dace2f478e042eaa15606c7efccb700797660629da387eb289b9323"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca244fa73f50a800cf8c3ebf7fd93149ec37f5cb9596aa8873ae2c1d23498601"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d9d971ec1e79906046aa3ca266de79eac42f1dbf3612a05dc9368125952bd1a1"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7e007132af78ea9df29495dbf7b5824cb71648d7133cf7848a2a5dd00d36f9ff"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7313ce6a199651c4ed9d7e4cfb4aa56fe923b1adf9af3b420ee14e6d9a73df65"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp310-cp310-win32.whl", hash = "sha256:c4a549890a45f57f1ebf99c067a4ad0cb423a05544accaf2b065246827ed9603"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:835fb5e38fd89328e9c81067fd642b3593c33e1e17e2fdbf77f5676abb14a156"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2ec4f2d48ae59bbb9d1f9d7efb9236ab81429a764dedca114f5fdabbc3788013"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608e7073dfa9e38a85d38474c082d4281f4ce276ac0010224eaba11e929dd53a"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65608c35bfb8a76763f37036547f7adfd09270fbdbf96608be2bead319728fcd"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2bfb563d0211ce16b63c7cb9395d2c682a23187f54c3d79bfec33e6705473c6"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da25303d91526aac3672ee6d49a2f3db2d9502a4a60b55519feb1a4c7714e07d"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9cad97ab29dfc3f0249b483412c85c8ef4766d96cdf9dcf5a1e3caa3f3661cf1"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:085fd3201e7b12809f9e6e9bc1e5c96a368c8523fad5afb02afe3c051ae4afcc"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1bea30e9bf331f3fef67e0a3877b2288593c98a21ccb2cf29b74c581a4eb3af0"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp311-cp311-win32.whl", hash = "sha256:7df70907e00c970c60b9ef2938d894a9381f38e6b9db73c5be35e59d92e06625"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:e55e40ff0cc8cc5c07996915ad367fa47da6b3fc091fdadca7f5403239c5fec3"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a6e40afa7f45939ca356f348c8e23048e02cb109ced1eb8420961b2f40fb373a"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf877ab4ed6e302ec1d04952ca358b381a882fbd9d1b07cccbfd61783561f98a"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63ba06c9941e46fa389d389644e2d8225e0e3e5ebcc4ff1ea8506dce646f8c8a"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f1cd098434e83e656abf198f103a8207a8187c0fc110306691a2e94a78d0abb2"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:55f44b440d491028addb3b88f72207d71eeebfb7b5dbf0643f7c023ae1fba619"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a6f2fcca746e8d5910e18782f976489939d54a91f9411c32051b4aab2bd7c513"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0b462104ba25f1ac006fdab8b6a01ebbfbce9ed37fd37fd4acd70c67c973e460"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp37-cp37m-win32.whl", hash = "sha256:7668b52e102d0ed87cb082380a7e2e1e78737ddecdde129acadb0eccc5423859"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6d6607f98fcf17e534162f0709aaad3ab7a96032723d8ac8750ffe17ae5a0666"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a806db027852538d2ad7555b203300173dd1b77ba116de92da9afbc3a3be3eed"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a4abaec6ca3ad8660690236d11bfe28dfd707778e2442b45addd2f086d6ef094"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f03a532d7dee1bed20bc4884194a16160a2de9ffc6354b3878ec9682bb623c54"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4cf06cdc1dda95223e9d2d3c58d3b178aa5dacb35ee7e3bbac10e4e1faacb419"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22731d79ed2eb25059ae3df1dfc9cb1546691cc41f4e3130fe6bfbc3ecbbecfa"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f8ffb705ffcf5ddd0e80b65ddf7bed7ee4f5a441ea7d3419e861a12eaf41af58"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8db032bf0ce9022a8e41a22598eefc802314e81b879ae093f36ce9ddf39ab1ba"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2298c859cfc5463f1b64bd55cb3e602528db6fa0f3cfd568d3605c50678f8f03"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp38-cp38-win32.whl", hash = "sha256:50c42830a633fa0cf9e7d27664637532791bfc31c731a87b202d2d8ac40c3ea2"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:bb06feb762bade6bf3c8b844462274db0c76acc95c52abe8dbed28ae3d44a147"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:99625a92da8229df6d44335e6fcc558a5037dd0a760e11d84be2260e6f37002f"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8bca7e26c1dd751236cfb0c6c72d4ad61d986e9a41bbf76cb445f69488b2a2bd"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40627dcf047dadb22cd25ea7ecfe9cbf3bbbad0482ee5920b582f3809c97654f"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40dfd3fefbef579ee058f139733ac336312663c6706d1163b82b3003fb1925c4"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:090376d812fb6ac5f171e5938e82e7f2d7adc2b629101cec0db8b267815c85e2"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2e7821bffe00aa6bd07a23913b7f4e01328c3d5cc0b40b36c0bd81d362faeb65"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c0a33bc9f02c2b17c3ea382f91b4db0e6cde90b63b296422a939886a7a80de1c"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b8526c6d437855442cdd3d87eede9c425c4445ea011ca38d937db299382e6fa3"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp39-cp39-win32.whl", hash = "sha256:137678c63c977754abe9086a3ec011e8fd985ab90631145dfb9294ad09c102a7"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed"},
 | 
				
			||||||
 | 
					    {file = "MarkupSafe-2.1.2.tar.gz", hash = "sha256:abcabc8c2b26036d62d4c746381a6f7cf60aafcc653198ad678306986b09450d"},
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "priority"
 | 
				
			||||||
 | 
					version = "2.0.0"
 | 
				
			||||||
 | 
					description = "A pure-Python implementation of the HTTP/2 priority tree"
 | 
				
			||||||
 | 
					optional = false
 | 
				
			||||||
 | 
					python-versions = ">=3.6.1"
 | 
				
			||||||
 | 
					files = [
 | 
				
			||||||
 | 
					    {file = "priority-2.0.0-py3-none-any.whl", hash = "sha256:6f8eefce5f3ad59baf2c080a664037bb4725cd0a790d53d59ab4059288faf6aa"},
 | 
				
			||||||
 | 
					    {file = "priority-2.0.0.tar.gz", hash = "sha256:c965d54f1b8d0d0b19479db3924c7c36cf672dbf2aec92d43fbdaf4492ba18c0"},
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "quart"
 | 
				
			||||||
 | 
					version = "0.18.4"
 | 
				
			||||||
 | 
					description = "A Python ASGI web microframework with the same API as Flask"
 | 
				
			||||||
 | 
					optional = false
 | 
				
			||||||
 | 
					python-versions = ">=3.7"
 | 
				
			||||||
 | 
					files = [
 | 
				
			||||||
 | 
					    {file = "quart-0.18.4-py3-none-any.whl", hash = "sha256:578a466bcd8c58b947b384ca3517c2a2f3bfeec8f58f4ff5038d4506ffee6be7"},
 | 
				
			||||||
 | 
					    {file = "quart-0.18.4.tar.gz", hash = "sha256:c1766f269cdb85daf9da67ba54170abf7839aca97304dcb4cd0778eabfb442c6"},
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[package.dependencies]
 | 
				
			||||||
 | 
					aiofiles = "*"
 | 
				
			||||||
 | 
					blinker = "<1.6"
 | 
				
			||||||
 | 
					click = ">=8.0.0"
 | 
				
			||||||
 | 
					hypercorn = ">=0.11.2"
 | 
				
			||||||
 | 
					itsdangerous = "*"
 | 
				
			||||||
 | 
					jinja2 = "*"
 | 
				
			||||||
 | 
					markupsafe = "*"
 | 
				
			||||||
 | 
					werkzeug = ">=2.2.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[package.extras]
 | 
				
			||||||
 | 
					docs = ["pydata_sphinx_theme"]
 | 
				
			||||||
 | 
					dotenv = ["python-dotenv"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "toml"
 | 
				
			||||||
 | 
					version = "0.10.2"
 | 
				
			||||||
 | 
					description = "Python Library for Tom's Obvious, Minimal Language"
 | 
				
			||||||
 | 
					optional = false
 | 
				
			||||||
 | 
					python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
 | 
				
			||||||
 | 
					files = [
 | 
				
			||||||
 | 
					    {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
 | 
				
			||||||
 | 
					    {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "uvicorn"
 | 
				
			||||||
 | 
					version = "0.22.0"
 | 
				
			||||||
 | 
					description = "The lightning-fast ASGI server."
 | 
				
			||||||
 | 
					optional = false
 | 
				
			||||||
 | 
					python-versions = ">=3.7"
 | 
				
			||||||
 | 
					files = [
 | 
				
			||||||
 | 
					    {file = "uvicorn-0.22.0-py3-none-any.whl", hash = "sha256:e9434d3bbf05f310e762147f769c9f21235ee118ba2d2bf1155a7196448bd996"},
 | 
				
			||||||
 | 
					    {file = "uvicorn-0.22.0.tar.gz", hash = "sha256:79277ae03db57ce7d9aa0567830bbb51d7a612f54d6e1e3e92da3ef24c2c8ed8"},
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[package.dependencies]
 | 
				
			||||||
 | 
					click = ">=7.0"
 | 
				
			||||||
 | 
					h11 = ">=0.8"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[package.extras]
 | 
				
			||||||
 | 
					standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "werkzeug"
 | 
				
			||||||
 | 
					version = "2.3.4"
 | 
				
			||||||
 | 
					description = "The comprehensive WSGI web application library."
 | 
				
			||||||
 | 
					optional = false
 | 
				
			||||||
 | 
					python-versions = ">=3.8"
 | 
				
			||||||
 | 
					files = [
 | 
				
			||||||
 | 
					    {file = "Werkzeug-2.3.4-py3-none-any.whl", hash = "sha256:48e5e61472fee0ddee27ebad085614ebedb7af41e88f687aaf881afb723a162f"},
 | 
				
			||||||
 | 
					    {file = "Werkzeug-2.3.4.tar.gz", hash = "sha256:1d5a58e0377d1fe39d061a5de4469e414e78ccb1e1e59c0f5ad6fa1c36c52b76"},
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[package.dependencies]
 | 
				
			||||||
 | 
					MarkupSafe = ">=2.1.1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[package.extras]
 | 
				
			||||||
 | 
					watchdog = ["watchdog (>=2.3)"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[[package]]
 | 
				
			||||||
 | 
					name = "wsproto"
 | 
				
			||||||
 | 
					version = "1.2.0"
 | 
				
			||||||
 | 
					description = "WebSockets state-machine based protocol implementation"
 | 
				
			||||||
 | 
					optional = false
 | 
				
			||||||
 | 
					python-versions = ">=3.7.0"
 | 
				
			||||||
 | 
					files = [
 | 
				
			||||||
 | 
					    {file = "wsproto-1.2.0-py3-none-any.whl", hash = "sha256:b9acddd652b585d75b20477888c56642fdade28bdfd3579aa24a4d2c037dd736"},
 | 
				
			||||||
 | 
					    {file = "wsproto-1.2.0.tar.gz", hash = "sha256:ad565f26ecb92588a3e43bc3d96164de84cd9902482b130d0ddbaa9664a85065"},
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[package.dependencies]
 | 
				
			||||||
 | 
					h11 = ">=0.9.0,<1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[metadata]
 | 
				
			||||||
 | 
					lock-version = "2.0"
 | 
				
			||||||
 | 
					python-versions = "^3.10"
 | 
				
			||||||
 | 
					content-hash = "1b974e20fe2d5b7b2568181b9aa7dfecccd57ce5169f0caeb51723eada05a9e5"
 | 
				
			||||||
							
								
								
									
										18
									
								
								pyproject.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								pyproject.toml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					[tool.poetry]
 | 
				
			||||||
 | 
					name = "fablab-bottle-clip-generator"
 | 
				
			||||||
 | 
					version = "0.0.1"
 | 
				
			||||||
 | 
					description = ""
 | 
				
			||||||
 | 
					authors = ["Fabian Müller <fabian@fablab-altmuehlfranken.de>"]
 | 
				
			||||||
 | 
					license = "MIT"
 | 
				
			||||||
 | 
					readme = "README.md"
 | 
				
			||||||
 | 
					packages = [{include = "app"}]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[tool.poetry.dependencies]
 | 
				
			||||||
 | 
					python = "^3.10"
 | 
				
			||||||
 | 
					quart = "^0.18.4"
 | 
				
			||||||
 | 
					uvicorn = "^0.22.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[build-system]
 | 
				
			||||||
 | 
					requires = ["poetry-core"]
 | 
				
			||||||
 | 
					build-backend = "poetry.core.masonry.api"
 | 
				
			||||||
		Reference in New Issue
	
	Block a user