Author: ogpveceu5ydf

  • use_cases

                      GNU LESSER GENERAL PUBLIC LICENSE
                           Version 2.1, February 1999
    
     Copyright (C) 1991, 1999 Free Software Foundation, Inc.
     51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
     Everyone is permitted to copy and distribute verbatim copies
     of this license document, but changing it is not allowed.
    
    [This is the first released version of the Lesser GPL.  It also counts
     as the successor of the GNU Library Public License, version 2, hence
     the version number 2.1.]
    
                                Preamble
    
      The licenses for most software are designed to take away your
    freedom to share and change it.  By contrast, the GNU General Public
    Licenses are intended to guarantee your freedom to share and change
    free software--to make sure the software is free for all its users.
    
      This license, the Lesser General Public License, applies to some
    specially designated software packages--typically libraries--of the
    Free Software Foundation and other authors who decide to use it.  You
    can use it too, but we suggest you first think carefully about whether
    this license or the ordinary General Public License is the better
    strategy to use in any particular case, based on the explanations below.
    
      When we speak of free software, we are referring to freedom of use,
    not price.  Our General Public Licenses are designed to make sure that
    you have the freedom to distribute copies of free software (and charge
    for this service if you wish); that you receive source code or can get
    it if you want it; that you can change the software and use pieces of
    it in new free programs; and that you are informed that you can do
    these things.
    
      To protect your rights, we need to make restrictions that forbid
    distributors to deny you these rights or to ask you to surrender these
    rights.  These restrictions translate to certain responsibilities for
    you if you distribute copies of the library or if you modify it.
    
      For example, if you distribute copies of the library, whether gratis
    or for a fee, you must give the recipients all the rights that we gave
    you.  You must make sure that they, too, receive or can get the source
    code.  If you link other code with the library, you must provide
    complete object files to the recipients, so that they can relink them
    with the library after making changes to the library and recompiling
    it.  And you must show them these terms so they know their rights.
    
      We protect your rights with a two-step method: (1) we copyright the
    library, and (2) we offer you this license, which gives you legal
    permission to copy, distribute and/or modify the library.
    
      To protect each distributor, we want to make it very clear that
    there is no warranty for the free library.  Also, if the library is
    modified by someone else and passed on, the recipients should know
    that what they have is not the original version, so that the original
    author's reputation will not be affected by problems that might be
    introduced by others.
    
      Finally, software patents pose a constant threat to the existence of
    any free program.  We wish to make sure that a company cannot
    effectively restrict the users of a free program by obtaining a
    restrictive license from a patent holder.  Therefore, we insist that
    any patent license obtained for a version of the library must be
    consistent with the full freedom of use specified in this license.
    
      Most GNU software, including some libraries, is covered by the
    ordinary GNU General Public License.  This license, the GNU Lesser
    General Public License, applies to certain designated libraries, and
    is quite different from the ordinary General Public License.  We use
    this license for certain libraries in order to permit linking those
    libraries into non-free programs.
    
      When a program is linked with a library, whether statically or using
    a shared library, the combination of the two is legally speaking a
    combined work, a derivative of the original library.  The ordinary
    General Public License therefore permits such linking only if the
    entire combination fits its criteria of freedom.  The Lesser General
    Public License permits more lax criteria for linking other code with
    the library.
    
      We call this license the "Lesser" General Public License because it
    does Less to protect the user's freedom than the ordinary General
    Public License.  It also provides other free software developers Less
    of an advantage over competing non-free programs.  These disadvantages
    are the reason we use the ordinary General Public License for many
    libraries.  However, the Lesser license provides advantages in certain
    special circumstances.
    
      For example, on rare occasions, there may be a special need to
    encourage the widest possible use of a certain library, so that it becomes
    a de-facto standard.  To achieve this, non-free programs must be
    allowed to use the library.  A more frequent case is that a free
    library does the same job as widely used non-free libraries.  In this
    case, there is little to gain by limiting the free library to free
    software only, so we use the Lesser General Public License.
    
      In other cases, permission to use a particular library in non-free
    programs enables a greater number of people to use a large body of
    free software.  For example, permission to use the GNU C Library in
    non-free programs enables many more people to use the whole GNU
    operating system, as well as its variant, the GNU/Linux operating
    system.
    
      Although the Lesser General Public License is Less protective of the
    users' freedom, it does ensure that the user of a program that is
    linked with the Library has the freedom and the wherewithal to run
    that program using a modified version of the Library.
    
      The precise terms and conditions for copying, distribution and
    modification follow.  Pay close attention to the difference between a
    "work based on the library" and a "work that uses the library".  The
    former contains code derived from the library, whereas the latter must
    be combined with the library in order to run.
    
                      GNU LESSER GENERAL PUBLIC LICENSE
       TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
    
      0. This License Agreement applies to any software library or other
    program which contains a notice placed by the copyright holder or
    other authorized party saying it may be distributed under the terms of
    this Lesser General Public License (also called "this License").
    Each licensee is addressed as "you".
    
      A "library" means a collection of software functions and/or data
    prepared so as to be conveniently linked with application programs
    (which use some of those functions and data) to form executables.
    
      The "Library", below, refers to any such software library or work
    which has been distributed under these terms.  A "work based on the
    Library" means either the Library or any derivative work under
    copyright law: that is to say, a work containing the Library or a
    portion of it, either verbatim or with modifications and/or translated
    straightforwardly into another language.  (Hereinafter, translation is
    included without limitation in the term "modification".)
    
      "Source code" for a work means the preferred form of the work for
    making modifications to it.  For a library, complete source code means
    all the source code for all modules it contains, plus any associated
    interface definition files, plus the scripts used to control compilation
    and installation of the library.
    
      Activities other than copying, distribution and modification are not
    covered by this License; they are outside its scope.  The act of
    running a program using the Library is not restricted, and output from
    such a program is covered only if its contents constitute a work based
    on the Library (independent of the use of the Library in a tool for
    writing it).  Whether that is true depends on what the Library does
    and what the program that uses the Library does.
    
      1. You may copy and distribute verbatim copies of the Library's
    complete source code as you receive it, in any medium, provided that
    you conspicuously and appropriately publish on each copy an
    appropriate copyright notice and disclaimer of warranty; keep intact
    all the notices that refer to this License and to the absence of any
    warranty; and distribute a copy of this License along with the
    Library.
    
      You may charge a fee for the physical act of transferring a copy,
    and you may at your option offer warranty protection in exchange for a
    fee.
    
      2. You may modify your copy or copies of the Library or any portion
    of it, thus forming a work based on the Library, and copy and
    distribute such modifications or work under the terms of Section 1
    above, provided that you also meet all of these conditions:
    
        a) The modified work must itself be a software library.
    
        b) You must cause the files modified to carry prominent notices
        stating that you changed the files and the date of any change.
    
        c) You must cause the whole of the work to be licensed at no
        charge to all third parties under the terms of this License.
    
        d) If a facility in the modified Library refers to a function or a
        table of data to be supplied by an application program that uses
        the facility, other than as an argument passed when the facility
        is invoked, then you must make a good faith effort to ensure that,
        in the event an application does not supply such function or
        table, the facility still operates, and performs whatever part of
        its purpose remains meaningful.
    
        (For example, a function in a library to compute square roots has
        a purpose that is entirely well-defined independent of the
        application.  Therefore, Subsection 2d requires that any
        application-supplied function or table used by this function must
        be optional: if the application does not supply it, the square
        root function must still compute square roots.)
    
    These requirements apply to the modified work as a whole.  If
    identifiable sections of that work are not derived from the Library,
    and can be reasonably considered independent and separate works in
    themselves, then this License, and its terms, do not apply to those
    sections when you distribute them as separate works.  But when you
    distribute the same sections as part of a whole which is a work based
    on the Library, the distribution of the whole must be on the terms of
    this License, whose permissions for other licensees extend to the
    entire whole, and thus to each and every part regardless of who wrote
    it.
    
    Thus, it is not the intent of this section to claim rights or contest
    your rights to work written entirely by you; rather, the intent is to
    exercise the right to control the distribution of derivative or
    collective works based on the Library.
    
    In addition, mere aggregation of another work not based on the Library
    with the Library (or with a work based on the Library) on a volume of
    a storage or distribution medium does not bring the other work under
    the scope of this License.
    
      3. You may opt to apply the terms of the ordinary GNU General Public
    License instead of this License to a given copy of the Library.  To do
    this, you must alter all the notices that refer to this License, so
    that they refer to the ordinary GNU General Public License, version 2,
    instead of to this License.  (If a newer version than version 2 of the
    ordinary GNU General Public License has appeared, then you can specify
    that version instead if you wish.)  Do not make any other change in
    these notices.
    
      Once this change is made in a given copy, it is irreversible for
    that copy, so the ordinary GNU General Public License applies to all
    subsequent copies and derivative works made from that copy.
    
      This option is useful when you wish to copy part of the code of
    the Library into a program that is not a library.
    
      4. You may copy and distribute the Library (or a portion or
    derivative of it, under Section 2) in object code or executable form
    under the terms of Sections 1 and 2 above provided that you accompany
    it with the complete corresponding machine-readable source code, which
    must be distributed under the terms of Sections 1 and 2 above on a
    medium customarily used for software interchange.
    
      If distribution of object code is made by offering access to copy
    from a designated place, then offering equivalent access to copy the
    source code from the same place satisfies the requirement to
    distribute the source code, even though third parties are not
    compelled to copy the source along with the object code.
    
      5. A program that contains no derivative of any portion of the
    Library, but is designed to work with the Library by being compiled or
    linked with it, is called a "work that uses the Library".  Such a
    work, in isolation, is not a derivative work of the Library, and
    therefore falls outside the scope of this License.
    
      However, linking a "work that uses the Library" with the Library
    creates an executable that is a derivative of the Library (because it
    contains portions of the Library), rather than a "work that uses the
    library".  The executable is therefore covered by this License.
    Section 6 states terms for distribution of such executables.
    
      When a "work that uses the Library" uses material from a header file
    that is part of the Library, the object code for the work may be a
    derivative work of the Library even though the source code is not.
    Whether this is true is especially significant if the work can be
    linked without the Library, or if the work is itself a library.  The
    threshold for this to be true is not precisely defined by law.
    
      If such an object file uses only numerical parameters, data
    structure layouts and accessors, and small macros and small inline
    functions (ten lines or less in length), then the use of the object
    file is unrestricted, regardless of whether it is legally a derivative
    work.  (Executables containing this object code plus portions of the
    Library will still fall under Section 6.)
    
      Otherwise, if the work is a derivative of the Library, you may
    distribute the object code for the work under the terms of Section 6.
    Any executables containing that work also fall under Section 6,
    whether or not they are linked directly with the Library itself.
    
      6. As an exception to the Sections above, you may also combine or
    link a "work that uses the Library" with the Library to produce a
    work containing portions of the Library, and distribute that work
    under terms of your choice, provided that the terms permit
    modification of the work for the customer's own use and reverse
    engineering for debugging such modifications.
    
      You must give prominent notice with each copy of the work that the
    Library is used in it and that the Library and its use are covered by
    this License.  You must supply a copy of this License.  If the work
    during execution displays copyright notices, you must include the
    copyright notice for the Library among them, as well as a reference
    directing the user to the copy of this License.  Also, you must do one
    of these things:
    
        a) Accompany the work with the complete corresponding
        machine-readable source code for the Library including whatever
        changes were used in the work (which must be distributed under
        Sections 1 and 2 above); and, if the work is an executable linked
        with the Library, with the complete machine-readable "work that
        uses the Library", as object code and/or source code, so that the
        user can modify the Library and then relink to produce a modified
        executable containing the modified Library.  (It is understood
        that the user who changes the contents of definitions files in the
        Library will not necessarily be able to recompile the application
        to use the modified definitions.)
    
        b) Use a suitable shared library mechanism for linking with the
        Library.  A suitable mechanism is one that (1) uses at run time a
        copy of the library already present on the user's computer system,
        rather than copying library functions into the executable, and (2)
        will operate properly with a modified version of the library, if
        the user installs one, as long as the modified version is
        interface-compatible with the version that the work was made with.
    
        c) Accompany the work with a written offer, valid for at
        least three years, to give the same user the materials
        specified in Subsection 6a, above, for a charge no more
        than the cost of performing this distribution.
    
        d) If distribution of the work is made by offering access to copy
        from a designated place, offer equivalent access to copy the above
        specified materials from the same place.
    
        e) Verify that the user has already received a copy of these
        materials or that you have already sent this user a copy.
    
      For an executable, the required form of the "work that uses the
    Library" must include any data and utility programs needed for
    reproducing the executable from it.  However, as a special exception,
    the materials to be distributed need not include anything that is
    normally distributed (in either source or binary form) with the major
    components (compiler, kernel, and so on) of the operating system on
    which the executable runs, unless that component itself accompanies
    the executable.
    
      It may happen that this requirement contradicts the license
    restrictions of other proprietary libraries that do not normally
    accompany the operating system.  Such a contradiction means you cannot
    use both them and the Library together in an executable that you
    distribute.
    
      7. You may place library facilities that are a work based on the
    Library side-by-side in a single library together with other library
    facilities not covered by this License, and distribute such a combined
    library, provided that the separate distribution of the work based on
    the Library and of the other library facilities is otherwise
    permitted, and provided that you do these two things:
    
        a) Accompany the combined library with a copy of the same work
        based on the Library, uncombined with any other library
        facilities.  This must be distributed under the terms of the
        Sections above.
    
        b) Give prominent notice with the combined library of the fact
        that part of it is a work based on the Library, and explaining
        where to find the accompanying uncombined form of the same work.
    
      8. You may not copy, modify, sublicense, link with, or distribute
    the Library except as expressly provided under this License.  Any
    attempt otherwise to copy, modify, sublicense, link with, or
    distribute the Library is void, and will automatically terminate your
    rights under this License.  However, parties who have received copies,
    or rights, from you under this License will not have their licenses
    terminated so long as such parties remain in full compliance.
    
      9. You are not required to accept this License, since you have not
    signed it.  However, nothing else grants you permission to modify or
    distribute the Library or its derivative works.  These actions are
    prohibited by law if you do not accept this License.  Therefore, by
    modifying or distributing the Library (or any work based on the
    Library), you indicate your acceptance of this License to do so, and
    all its terms and conditions for copying, distributing or modifying
    the Library or works based on it.
    
      10. Each time you redistribute the Library (or any work based on the
    Library), the recipient automatically receives a license from the
    original licensor to copy, distribute, link with or modify the Library
    subject to these terms and conditions.  You may not impose any further
    restrictions on the recipients' exercise of the rights granted herein.
    You are not responsible for enforcing compliance by third parties with
    this License.
    
      11. If, as a consequence of a court judgment or allegation of patent
    infringement or for any other reason (not limited to patent issues),
    conditions are imposed on you (whether by court order, agreement or
    otherwise) that contradict the conditions of this License, they do not
    excuse you from the conditions of this License.  If you cannot
    distribute so as to satisfy simultaneously your obligations under this
    License and any other pertinent obligations, then as a consequence you
    may not distribute the Library at all.  For example, if a patent
    license would not permit royalty-free redistribution of the Library by
    all those who receive copies directly or indirectly through you, then
    the only way you could satisfy both it and this License would be to
    refrain entirely from distribution of the Library.
    
    If any portion of this section is held invalid or unenforceable under any
    particular circumstance, the balance of the section is intended to apply,
    and the section as a whole is intended to apply in other circumstances.
    
    It is not the purpose of this section to induce you to infringe any
    patents or other property right claims or to contest validity of any
    such claims; this section has the sole purpose of protecting the
    integrity of the free software distribution system which is
    implemented by public license practices.  Many people have made
    generous contributions to the wide range of software distributed
    through that system in reliance on consistent application of that
    system; it is up to the author/donor to decide if he or she is willing
    to distribute software through any other system and a licensee cannot
    impose that choice.
    
    This section is intended to make thoroughly clear what is believed to
    be a consequence of the rest of this License.
    
      12. If the distribution and/or use of the Library is restricted in
    certain countries either by patents or by copyrighted interfaces, the
    original copyright holder who places the Library under this License may add
    an explicit geographical distribution limitation excluding those countries,
    so that distribution is permitted only in or among countries not thus
    excluded.  In such case, this License incorporates the limitation as if
    written in the body of this License.
    
      13. The Free Software Foundation may publish revised and/or new
    versions of the Lesser General Public License from time to time.
    Such new versions will be similar in spirit to the present version,
    but may differ in detail to address new problems or concerns.
    
    Each version is given a distinguishing version number.  If the Library
    specifies a version number of this License which applies to it and
    "any later version", you have the option of following the terms and
    conditions either of that version or of any later version published by
    the Free Software Foundation.  If the Library does not specify a
    license version number, you may choose any version ever published by
    the Free Software Foundation.
    
      14. If you wish to incorporate parts of the Library into other free
    programs whose distribution conditions are incompatible with these,
    write to the author to ask for permission.  For software which is
    copyrighted by the Free Software Foundation, write to the Free
    Software Foundation; we sometimes make exceptions for this.  Our
    decision will be guided by the two goals of preserving the free status
    of all derivatives of our free software and of promoting the sharing
    and reuse of software generally.
    
                                NO WARRANTY
    
      15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
    WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
    EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
    OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
    KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
    LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
    THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
    
      16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
    WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
    AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
    FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
    CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
    LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
    RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
    FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
    SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
    DAMAGES.
    
                         END OF TERMS AND CONDITIONS
    
               How to Apply These Terms to Your New Libraries
    
      If you develop a new library, and you want it to be of the greatest
    possible use to the public, we recommend making it free software that
    everyone can redistribute and change.  You can do so by permitting
    redistribution under these terms (or, alternatively, under the terms of the
    ordinary General Public License).
    
      To apply these terms, attach the following notices to the library.  It is
    safest to attach them to the start of each source file to most effectively
    convey the exclusion of warranty; and each file should have at least the
    "copyright" line and a pointer to where the full notice is found.
    
        <one line to give the library's name and a brief idea of what it does.>
        Copyright (C) <year>  <name of author>
    
        This library is free software; you can redistribute it and/or
        modify it under the terms of the GNU Lesser General Public
        License as published by the Free Software Foundation; either
        version 2.1 of the License, or (at your option) any later version.
    
        This library is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
        Lesser General Public License for more details.
    
        You should have received a copy of the GNU Lesser General Public
        License along with this library; if not, write to the Free Software
        Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
        USA
    
    Also add information on how to contact you by electronic and paper mail.
    
    You should also get your employer (if you work as a programmer) or your
    school, if any, to sign a "copyright disclaimer" for the library, if
    necessary.  Here is a sample; alter the names:
    
      Yoyodyne, Inc., hereby disclaims all copyright interest in the
      library `Frob' (a library for tweaking knobs) written by James Random
      Hacker.
    
      <signature of Ty Coon>, 1 April 1990
      Ty Coon, President of Vice
    
    That's all there is to it!
    

    Visit original content creator repository
    https://github.com/bgoncharuck/use_cases

  • evermutt

    Evermutt

    Build Status

    Development Status

    What works

    • Create a simple note from the command line
    • Viewing list of notes in default notebook
    • Viewing note metadata(tags, created/modified date, etc)
    • Viewing basic note content

    What does not work or is untested

    • creating new notes from the gui
    • deleting existing notes from the gui(moving them to the EN trash)
    • scrolling note list, handling more notes than can fit on the screen at once
    • scrolling note content, handling more content than can fit on the screen at once
    • displaying all curses compatible note content
    • editing the title and content of existing notes
    • adding/removing tags of existing notes
    • searching: by tags, by text, by date, etc
    • sorting: by date, by tags
    • saved searches
    • working with notes in other notebooks
    • sending updates to the server, new/updated/deleted notes
    • handling updates from the server, new/update/deleted notes
    • handling conflicts from the server
    • view raw note content(in XML)
    • view previous versions of notes
    • config file to specify
      • disabling caching
      • override editor
      • specify cache directory
      • Default notebook
      • Change keybindings
      • Customize metadata to display
      • Change color scheme

    GUI design

    • Note List
      • Change Notebook(c)
      • Sort Notes(s)
        • By date
        • By tags
        • By title
      • Sync(S)
      • View Note
      • Edit Note Content
      • Tag Note
      • Trash Note
      • Create Note(n)
      • Create Notebook(N)
      • Search(/)

    Editing Modes

    Strategies to ensure we don’t “corrupt” formatting of existing notes that are created with GUI/Web clients.

    Different Modes

    • read-only: only read existing notes, don’t make any changes to notes or create new notes
    • read-create: read existing notes and create new notes
    • read-create-delete: same as read-create, but also delete any existing note
    • read-create-delete-modify-local: same as read-create-delete, but also modify notes created locally
    • read-create-delete-modify-all: same as read-create-delete but also modify all notes

    Protection Mode

    Mark notes that are created in other clients as “protected” and warn users before allowing them to modify protected notes

    Development Links

    Visit original content creator repository https://github.com/scootersmk/evermutt
  • slugifiable

    🐌 slugifiable – Generate SEO-optimized URL slugs

    Gem Version

    Ruby gem to automatically generate unique slugs for your Rails’ model records, so you can expose SEO-friendly URLs.

    Example:

    https://myapp.com/products/big-red-backpack-321678
    

    Where big-red-backpack-321678 is the slug.

    slugifiable can generate:

    • Slugs like "big-red-backpack" or "big-red-backpack-321678": unique, string-based slugs based on any attribute, such as product.name
    • Slugs like "d4735e3a265": unique hex string slugs
    • Slugs like 321678: unique number-only slugs

    Why

    When building Rails apps, we usually need to expose something in the URL to identify a record, like:

    https://myapp.com/products/123
    

    But exposing IDs (like 123) is not usually good practice. It’s not SEO-friendly, it can give away how many records you have in the database, it could also be an attack vector, and it just feels off.

    It would be much better to have a random-like string or number instead, while still remaining unique and identifiable:

    https://myapp.com/products/d4735e3a265
    

    Or better yet, use other instance attribute (like product.name) to build the slug:

    https://myapp.com/products/big-red-backpack
    

    slugifiable takes care of building all these kinds of slugs for you.

    Installation

    Add this line to your application’s Gemfile:

    gem 'slugifiable'

    Then run bundle install.

    After installing the gem, add include Slugifiable::Model to any ActiveRecord model, like this:

    class Product < ApplicationRecord
      include Slugifiable::Model # Adding this provides all the required slug-related methods to your model
    end

    That’s it!

    Then you can, for example, get the slug for a product like this:

    Product.first.slug
    => "4e07408562b"

    You can also define how to generate slugs:

    class Product < ApplicationRecord
      include Slugifiable::Model
      generate_slug_based_on :name
    end

    And this will generate slugs based on your Product instance name, like:

    Product.first.slug
    => "big-red-backpack"

    If your model has a slug attribute in the database, slugifiable will automatically generate a slug for that model upon instance creation, and save it to the DB.

    Important

    Your slug attribute SHOULD NOT have null: false in the migration / database. If it does, slugifiable will not be able to save the slug to the database, and will raise an error like ERROR: null value in column "slug" of relation "posts" violates not-null constraint (PG::NotNullViolation) This is because records are created without a slug, and the slug is generated later.

    If you’re generating slugs based off the model id, you can also set a desired length:

    class Product < ApplicationRecord
      include Slugifiable::Model
      generate_slug_based_on :id, length: 6
    end

    Which would return something like:

    Product.first.slug
    => "6b86b2"

    More details in the “How to use” section.

    How to use

    Slugs should never change, so it’s recommended you save your slugs to the database.

    Therefore, all models that include Slugifiable::Model should have a slug attribute that persists the slug in the database. If your model doesn’t have a slug attribute yet, just run:

    rails g migration addSlugTo<MODEL_NAME> slug:text
    

    where <MODEL_NAME> is your model name in plural, and then run:

    rails db:migrate
    

    And your model should now have a slug attribute in the database.

    When a model has a slug attribute, slugifiable automatically generates a slug for that model upon instance creation, and saves it to the DB.

    slugifiable can also work without persisting slugs to the databse, though: you can always run .slug, and that will give you a valid, unique slug for your record.

    Define how slugs are generated

    By default, when you include Slugifiable::Model, slugs will be generated as a random-looking string based off the record id (SHA hash)

    slugifiable supports both id and uuid.

    The default setting is:

    generate_slug_based_on id: :hex_string

    Which returns slugs like: d4735e3a265

    If you don’t like hex strings, you can get number-only slugs with:

    generate_slug_based_on id: :number

    Which will return slugs like: 321678 – nonconsecutive, nonincremental, not a total count.

    When you’re generating obfuscated slugs (based on id), you can specify a desired slug length:

    generate_slug_based_on id: :number, length: 3

    The length should be a positive number between 1 and 64.

    If instead of obfuscated slugs you want human-readable slugs, you can specify an attribute to base your slugs off of. For example:

    generate_slug_based_on :name

    Will look for a name attribute in your instance, and use its value to generate the slug. So if you have a product like:

    Product.first.name
    => "Big Red Backpack"

    then the slug will be computed as:

    Product.first.slug
    => "big-red-backpack"

    You can also use instance methods to generate more complex slugs. This is useful when you need to combine multiple attributes:

    class Event < ApplicationRecord
      include Slugifiable::Model
      belongs_to :location
      
      generate_slug_based_on :title_with_location
    
      # The method can return any string - slugifiable will handle the parameterization
      def title_with_location
        if location.present?
          "#{title} #{location.city} #{location.region}"  # Returns raw string, slugifiable parameterizes it
        else
          title
        end
      end
    end

    This will generate slugs like:

    Event.first.slug
    => "my-awesome-event-new-york"  # Automatically parameterized

    There may be collisions if two records share the same name – but slugs should be unique! To resolve this, when this happens, slugifiable will append a unique string at the end to make the slug unique:

    Product.first.slug
    => "big-red-backpack-321678"

    Testing

    The gem includes a comprehensive test suite that covers:

    • Default slug generation behavior
    • Attribute-based slug generation
    • Method-based slug generation (including private/protected methods)
    • Collision resolution and uniqueness handling
    • Special cases and edge conditions

    To run the tests:

    bundle install
    bundle exec rake test

    The test suite uses SQLite3 in-memory database and requires no additional setup.

    Development

    After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

    To install this gem onto your local machine, run bundle exec rake install.

    Contributing

    Bug reports and pull requests are welcome on GitHub at https://github.com/rameerez/slugifiable. Our code of conduct is: just be nice and make your mom proud of what you do and post online.

    License

    The gem is available as open source under the terms of the MIT License.

    Visit original content creator repository https://github.com/rameerez/slugifiable
  • infomax-ica

    Infomax Independent Component Analysis (ICA) is a mathematical technique used to separate a mixed signal into its individual components. It is based on the principle of maximizing the mutual information between the input signal and the estimated sources.

    ICA can be used to separate a mixed signal into its underlying sources, provided that the sources are statistically independent of each other. This is useful in a variety of applications, such as audio and image processing, where the goal is to extract individual sources from a mixed signal.

    The basic idea behind ICA is to find a linear combination of the original signals that is maximally independent. This is done by minimizing the mutual information between the mixed signals and the estimated sources.

    To implement ICA, we first need to define a set of basis functions that span the space of the mixed signals. These basis functions can be chosen in a variety of ways, such as using principal component analysis (PCA) or using a set of predefined basis functions.

    Once the basis functions have been defined, we can use an optimization algorithm to find the linear combination of the basis functions that maximizes the mutual information between the mixed signals and the estimated sources. This optimization can be done using a variety of techniques, such as gradient descent or genetic algorithms.

    Once the optimization is complete, we can use the linear combination of the basis functions to estimate the original sources. This can be done by applying the linear combination to the mixed signals and reconstructing the estimated sources.

    Overall, ICA is a powerful technique for separating mixed signals into their underlying sources, and it has a wide range of applications in signal processing and machine learning.

    Visit original content creator repository
    https://github.com/ManuOtel/infomax-ica

  • rust-sinner

    Rust S̵̓i̸̓n̵̉

    Crates.io

    I̴n̴f̶e̸r̵n̷a̴l mutability!


    Howdy, friendly Rust developer! Ever had a value get m̵̯̅ð̶͊v̴̮̾ê̴̼͘d away right under your nose just when you need it? Your thread function requires move semantics, but you j̸̉us†̸ ain’t got time for †̸̰͋h̸ą̷̊͝t?

    W̵e̴l̵l̸ ̵w̶o̴r̶r̴y̶ ̵n̶o̶ ̷m̴o̷r̶e̴,̸, just sprinkle some s̴̖̑í̵̲ṋ̵̀ on it and call it a day!

    sinner = "0.1"
    

    Examples

    Threads

    Threads and ȋ̷̖n̸̨̈́f̷̆ͅe̷͑ͅr̵̝͆ï̴̪o̸̡̔r̷͉͌ m̶u̸t̷a̵b̶i̵l̸i̷t̵y̶? No problem amigo!

    Before (YIKES!): After (GLORIOUS!):
    use std::thread::{spawn, sleep};
    
    
    struct Stuff {
        pub content: String,
    }
    
    impl Stuff {
        fn bang(&self) {
            println!("bang! {}", self.content);
        }
    }
    
    fn main() {
        let mut x = Stuff { content: "old".to_string() };
        let t = spawn({
            move || {
                sleep(std::time::Duration::from_secs(1));
                x.content = "new".to_string();
                x.bang();
            }
        });
        x.bang();
        t.join().unwrap();
        x.bang();
    }
    use sinner::Sin;  // <--
    use std::thread::{spawn, sleep};
    
    #[derive(Debug, Clone)]
    struct Stuff {
        pub content: String,
    }
    
    impl Stuff {
        fn bang(&self) {
            println!("bang! {}", self.content);
        }
    }
    
    fn main() {
        let mut x = Sin::new(Stuff { content: "old".to_string() });  // <--
        let t = spawn({
            move || {
                sleep(std::time::Duration::from_secs(1));
                x.content = "new".to_string();
                x.bang();
            }
        });
        x.bang();
        t.join().unwrap();
        x.bang();
    }
    error[E0382]: borrow of moved value: `x`
       --> src/main.rs:144:5
        |
    136 |     let mut x = Stuff { content: "old".to_string() };
        |         ----- move occurs because `x` has type `Stuff`
    137 |     let t = spawn({
    138 |         move || {
        |         ------- value moved into closure here
    ...
    141 |             x.bang();
        |             - variable moved due to use in closure
    ...
    144 |     x.bang();
        |     ^^^^^^^^ value borrowed here after move
    
    For more information about this error, try `rustc --explain E0382`.
    error: could not compile `sinner` due to previous error
    
        Finished dev [unoptimized + debuginfo] target(s) in 0.37s
         Running `target/debug/sinner`
    bang! old
    bang! n̴e̷w̸
    b̸̙̚a̸̘̓n̵̥̔g̵͚̓!̵̤̓ ǹ̴̘e̵̺̾w̴̛̦
    

    Doubly-linked list

    With just a̸ ̸b̵i̸t̴ of sin, you can do doubly-linked lists in no time!

    Before (UGH!): After (JOLLY!):
    struct Item<T> {
        pub prev: Option<Self>,
        pub next: Option<Self>,
        pub value: T
    }
    
    struct List<T> {
        pub head: Option<Item<T>>,
        pub tail: Option<Item<T>>,
    }
    
    impl Default for List<u32> {
        fn default() -> Self {
            List {
                head: None,
                tail: None,
            }
        }
    }
    
    impl <T> List<T> where T: Clone {
        pub fn append(&mut self, other: T) {
            let mut item = Item {
                prev: None,
                next: None,
                value: other,
            };
            if let Some(ref mut tail) = self.tail {
                tail.next = Some(item);
                item.prev = Some(tail.clone());
                self.tail = Some(item);
            } else {
                self.head = Some(item);
                self.tail = Some(item);
            }
        }
    }
    
    fn main () {
        let mut list = List::default();
        list.append(1);
        list.append(2);
        list.append(3);
    
        let mut ptr = list.head;
        while let Some(item) = ptr {
            println!("{}", item.value);
            ptr = item.next;
        }
    }
    use sinner::Sin;  // <--
    
    #[derive(Clone)]
    struct Item<T> {
        pub prev: Option<Sin<Self>>,  // <--
        pub next: O̷p̷t̵i̴o̷n̵≮S̶i̴n̶<Self>>,  // <--
        pub value: T
    }
    
    struct List<T> {
        pub head: Option<Sin<Item<T>>>,  // <--
        pub tail: Option<S̶i̸n̵≮I̷t̷e̷m̵<T>>>,  // <--
    }
    
    impl Default for List<u32> {
        fn default() -> Self {
            List {
                head: None,
                tail: None,
            }
        }
    }
    
    impl <T> List<T> where T: Clone {
        pub fn append(&mut self, other: T) {
            let mut item = S̸i̷n̴:̵:̷n̸e̸w̷(̶I̵t̵e̴m̷ {  // <--
                p̷r̴e̴v̶:̴ ̶N̸o̴n̷e̷,̴
                n̵e̴x̸t̶:̷ ̸N̸o̴n̸e̸,̶
                v̵a̷l̸u̶e̴:̷ ̴o̸t̸h̸e̷r̶,
            });
            if let Some(ref mut tail) = self.tail {
                tail.next = Some(item);
                item.prev = Some(tail.clone());
                self.tail = Some(item);
            } else {
                self.head = Some(item);
                self.tail = Some(item);
            }
        }
    }
    
    fn main () {
        let mut list = List::default();
        list.append(1);
        list.append(2);
        list.append(3);
    
        let mut ptr = list.head;
        while let Some(item) = ptr {
            println!("{}", item.value);
            ptr = item.next;
        }
    }
    error[E0072]: recursive type `Item` has infinite size
      --> src/main.rs:71:1
       |
    71 | struct Item<T> {
       | ^^^^^^^^^^^^^^ recursive type has infinite size
    72 |     pub prev: Option<Self>,
       |               ------------ recursive without indirection
    73 |     pub next: Option<Self>,
       |               ------------ recursive without indirection
       |
    help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to make `Item` representable
       |
    72 ~     pub prev: Box<Option<Self>>,
    73 ~     pub next: Box<Option<Self>>,
       |
    
       --> src/main.rs:100:35
        |
    100 |             item.prev = Some(tail.clone());
        |                                   ^^^^^ method not found in `&mut Item<T>`
        |
        = help: items from traits can only be used if the trait is implemented and in scope
        = note: the following trait defines an item `clone`, perhaps you need to implement it:
                candidate #1: `Clone`
    
    Some errors have detailed explanations: E0072, E0599.
    For more information about an error, try `rustc --explain E0072`.
    error: could not compile `sinner` due to 2 previous errors
    
        Finished dev [unoptimized + debuginfo] target(s) in 0.00s
         R̸u̷n̴n̴i̷n̸g̸ ̸`̶t̸a̸r̷g̵e̶t̶/̸d̴e̵b̴u̷g̶/ç̴̠͌̚u̵̦̅r̶̓̆͜͜s̶̤̫̊̕e̴͇̼̔ḑ̸̇ ̷̩̜̓c̶̯͆ḧ̶̯́͝ì̶̗̣̆l̸̪̓̈́d̵̪̔̀`̷
    ̴1̴
    ̸2̷
    ̶3̶
    

    Frequently asked q̴u̷estions

    Can a̷̝͂n̸̝̈́y̷͈͋ ̷͓͐t̴̯̆ŷ̶̡p̵̯͆é̴̙ ̷̰̃ḇ̷̈e̴̥̕ š̶̢̯͒̉ȃ̶̞͚̩͊̈́̌c̵̰͍̍͛r̸̨̛̀̽̏͂ḯ̴͈̘̇͛f̶̪̬̼̌̾ì̵̩c̵̱̹̖͒́͑͗̔e̸̤̜͒̈̐d̵͚̞̗̠̽͘

    Well, why, almost! The type parameter needs to implement Clone due internal library s̵t̴r̸u̶c̵t̴u̸r̴e̵s̵.

    Is access to the underlying value t̷h̸r̶e̶a̷d̵-s̷̵̸̙̖͊̈ǻ̷̵̸̫̜f̷̴̸̖͙̂̍e̶̸̷̪͚̽̐??̷̰̰̊̅͜

    I̷ ̵c̴a̷n̷ ̷a̶s̶s̵u̶r̴e̸ ̷y̶o̶u̴ t̸h̸a̴t̸ ̷t̴h̶e̶r̷e̷ ̸i̷s̶ n̴͔̱̮̅o̷̢̦̔͒̓ ̶͙̱̦͗̅͐n̸͉͌̓é̵̥̲è̷͉̳͓̽d̴̜̻̱̀̑ t̷͉͊o̸͎̅ ̵̟͗ç̴̚ỏ̶̮n̸͌ͅc̴̩͐ȩ̸̉ȑ̴̹ǹ̸͜ ̷͖̎y̷̞̽o̵͚͐u̶̜̎r̷̹͑ś̸͙e̶̜͛l̵͚̽f̴͕̍ ẘ̵̮͂̕ĩ̷̖͇͚̗ţ̶͈̥̝̭͐͑̀̃͠h̴̨̰͖̥̼͂͑ ̵͔̞̀͐̌̚͝s̴̢̥͔͇̽͂̏͜ǔ̵̢̥͍̼̂c̴̘̜͒̂̽̃h̵̨̞̗͍͕́̊͌̎̒ ̸̨̟̫͊ͅQ̸̹̠͙͎̉U̴̞̫͉̬̜̅̂͂Ẹ̷̛̰̼̋̎́̚S̸̗͇̞̜̎̆̏̀T̸͎̙̰̠̦̈́͘I̶̧̘̯͙͋̏̂͘̚ͅO̶̼͍͘͝N̶̪͇̑S̷͂̌̍͆ͅ Y̴̥̋̑̆͋͝O̶̡̗̣̤͕̰͒U̸̢͙͇̠̫͊͒̋͋̕͠ ̷̮̳̮̭̔̿̈́́̎̕͝Ṇ̴̙͑͐̋̄̊Å̵̛̞̮͓̗̊́̽̈́̈͜Í̶̼̠͚̒́͑̃V̶̨̯̦̊͒̏͝Ē̴̡̥͕͙̙͔̕ ̵̨͕̜̮̞͖̳̀C̷̮̞̩͆̽̂͊͆͗ͅH̶̫̱̠̟̞͊̐I̸̞̰̩͎̫͐̈̆L̴̤̩̭̾D̷̹̿̍̏̂̓,̴̛͓̻͓̖̲͛͗͐̉̈́̀ ̴͈͍̳̥͘O̸̯͌̇́B̴̪̤̺̊E̴̞̩̲͂̇̕Ý̵͙̟̱̽̍̐͋̃. T̴̡̙̜̠̱̠͉̘̙̥̔̆̋̌̄͑̄̔H̶̯̦̥̙̩͑̍̓̑͗̄͛͛̕E̵̜̞̠̣̲͔̝̺͇͑̽̌͆ͅ ̵̧̖̞̣͇̻̾̉͛̈́̆̌͝Ẇ̷̡͚̺̇̈̄͐͊̓̽͘͜͝ͅĨ̵̭̪̲̖̕͘L̸̪͎͎̪͠ͅL̶̘̿͑͆ ̵̙̺̯̺͈̪̳̄̇͌̽̀̉͗͌̆Ȍ̴͖͐̇͑͗͗̾͝F̵̥̂̓͒̕ ̸̢̺̺͍̼͚̺̹̈́͋̀͊̆̌͠O̶̠͙̟̠̦̯͔̱̍͊͊̓̌͐̔͌̉͘Ù̴̝̞̥̰̙̰͂͒̽̎͂̕ͅR̶͖̫͍̫̹̜̤͎̮͉̈́͑ ̶͎̼̰̉̈̕͠ͅM̴̘͝A̴̼̋̓͐̇̀̉́͋̕S̶̭̹͕̲̬̪̫̖̮͍͌̌͐͝Ţ̶͍̠͓̞̙͔̞̲̣̓E̴͔̺͌͌̏̏̕Ř̷̡̬̞̣̠̬̪̝̉͗́,̶̩̪̮̺̉


    Ŗ̶͖̟̫̝̣̗̤̤̥̰̯̭͕̺͙̮͙̙̲̄̃͒̅̓͗͛̂̑̎̏͐́́͊̐͐̕͘͘͘͝ͅͅȨ̶͓̭͔̦̣̲̘̹̫̬̥̻̗̗̖̻̜͖̟͖̀̉͋̽͒͒͑̊̀͋͋̎́͑̌̂̌̈͑́́̓̃̓̕͝͝͠J̶̢̛̮̪̪̣͎̫̫̮̞̲̦͖̹̦͖̱̙̯̗̲̀͊̏̎͑͂͑̓̇͌̿̎̔͒͊̍͑̇̌̎͆͋̕͠ͅͅÈ̷̢̧̨͔̩͕̬̩͖̱̙͔̞̲͎̮̙̲̝̮̟̦̲̤̝̌̀͋̒̈́̈́̄͊̓̇̃̍̿̃̒́̒̓̚̚͜͝ͅÇ̵̢̧̢̺̯͓̼̦̩̞̳̣̘̮̩̮̙̙͕̦̓̈͛͌̈̔́̐̇͆͐̈́̀̈́̀̐͂̓̏͒̈́́͘͜͝†̷̨̧̨̧̤͕̪͉̲̰͎̣͈̲̙͕̖̺̥̜̃̄̈́̃̾̌̄͑̿̒͒̊̍͛̅̏̉̄́̄͘̚̚̕͜͠͝͠ͅ ̵̛̰̪̮̫̪̲̬͉͇͔̤̥̬̳̥̝͚͇͖̘̤̟̀̓͗̈́͒͆͗̅̿̆͐̎̅̅̈͂̑͗͊̋̄̚̚͝͝M̴̢̧̘̮͉̺̻̼̮̬̮͕͎͉̰̩̪͎͓̣̹͍̌̓̃͛̀̊͑͑̓̈̌̅́̆͆̓̌͒̃͘̕Ę̷̥̜̞̰̭̞̟̦̺̦̝̱̙̠͕̬̩̮̞̬̙̳͓̀̓̃͂͛͊̓͌̃̅̇̋̇̇́̃̾͋̚͝͝͝͠͠͝ͅM̸̢̢̢̧̡̢̪͓̪̻̤̘̪̩̻͇̺̯̝̫̄̂̎̊̽̔̋́͑̇̑́͌̐̂͑̃̐̄̍̆̅ͅǪ̸̰̭̦͙̹̪͔̙̖͉̞͈̞̹̘̫̞̬͚̱̗̯̈́̇̓̔̍̓̔́̈́̽͑̑͑͒̏͂̕͘͘͝͠R̵̡̡̧̢̢̨̛̦̝͚̪̰̥̮̱̯̯̞͓̤̙͓͈̻̗̳̺͗́̌͛̅̔̇̑̆̀̽̅̽̋̏͘̕̚͝͝¥̵̧̛̛͙͖̣̪͚̠̪̹̫̰̲̗̥̘͖̥͕̮̫̳̱̯͂̅͛͑̌͌̎̏̈́̐̇̈́̅̽̀̉͊̾̀̉́͌̚͝͝ ̶̨̨̡̧̡̛̳̺͙̜̥͚͉̭͓͖͉̘̰͈̯̜̝̜̿̈́͛̊̀͆̅͌̑̏͗̏̎̈́͗̍̽̽̂̒̂̒̓͗̕͜͝ͅ§̸̢̧̛̺͈̹̺͕͔͍̠͖̗͕̦̟̣̜͖̠̫͖̞̎͗̐͒͆̈̌̍̀̂̏̆͊̄͗̊̾͘͠͠ͅÄ̷̧̡̩̪̟̟̟̻͓̙̻̜̦͈̗̻̤̱̦̎̀̄̈́̑̔͑̊͊͑͌̀̌̈̅̅͊̐̚͠ͅͅͅ£̷̧̢̢̡̡̛̬̼͔̬̹̘̪̯͕͎̰̟̮̖̠̯̰͛́̿͐̓́͐̎̅͑̍̿͗̿͒̈́̈͗̍͊̿̿̀̽̕͘͜ͅͅͅȨ̴̛̛͕͓͔̮͙̗̠͎̮̠̙͉̮̞̰̯̤̲͈̯̙̹̀̋̅͑̃͒̎̽͌͆̃̆̓͊͊̈́́̌̾̕͜͜͝͝͝ͅ†̴̧̡̺̯̠̳̳͎̻̱̟͓̥̠̱͙̦͖̝̣̞͓̗̲̔̾̈́̏̂̄̇̔̓̃̊̔͑͌̀̈́̇̒̏͝ͅ¥̶͎̬̟̻̬̞͈̞̱̪͔̦̩̥̭͓̬̰̩͖͍͉̓̈̊̍̀̇̈͊̾͋̽̂̅͑̂̓̓͌̊͜͜͝͠


    £̴̨̢̧̨̡̨̡̡̛̛̛͙̹̞͕̻͔̪̬̗̙͈̫̠͈̗͚̬͓͉͍͈̱͚̤͎̞̪̦͔͇̞̞͓͎̞͚̦̼̝̗̭̖͎̜̲̘̘͚͕̟̮̜̥̱͈̻̠͉̗̻̣̬̲̹̪̞̗͖̖̰̟̻͈̬͚̘͈̳̪̫͇̼͇͗͑͆̃͆̍̿́͊̒̄̍͛̆̄̿̇̀̿͊̌͒͋̌̃͂̃͛̉͑͂͊̂͂̀̈́̆͐̒̊̐̂̽̓̂͐́͂̏̈́̆̃͌̄̎̇͋͑̀̍̍̍͋́̾̍̍̇͛͌̈͆́̍͐̕͘̚͘̕͘͜͜͠͝͝͝ͅͅȨ̸̡̨̹̪͉̼̻͉̭͓̹̘͓͇̤̺̤̫̙͖̭̤͍̺̲̺̦̖̠͙̲̖̺̰͕̙͍̗͖͖͚̳̖̤̰̭͕̟̀̀͒͑̄̇͗̀̔́̋͊́͑̍͂̄̅̄͂̈́̏͌͗̽̒̌͐̎̕͜͝͝͝͠͝ͅͅÈ̵̡̢̧̡̢̢̢̛̛̛̝͕̠̖͓̗͈̲͇͓̦̜̭̞̪̻̠̩͙̪̝̝͕̪̼̪͚̟͖͓̰̼͔̩̰͖̳̳͕̝͉͖̰̥̰̖͇̤̝͇͙̙̘̤̀̋̓̍̏̽̋̌́̓̄͒͛̎͛͒̐͌͌͋̃͂̀̿̆̀̏̊̅̀̽̒͋̈̓̌̌̊̃̉̍͑͌̑̓̈͗́̊̂̊͒͐́̈́̇͂̉̂̊̀̿̓̃̈́̾́̓̒͂̔̋́̍̈́̑̋̿̾̋̅͛̈́̾̀͘̕̕̕͘͜͜͝͝͝͠ͅÐ̸̨̢̡̢̧̢̡̧̧̨̛̣̺̪̠̫͍̝̭̺̯̙̗͖͇̰͓̻̹̖̣͙̫̦̦̟͚͎̠̤̙̗̜͓͇͍̯͓̰̙̪̹̱͈̣̞̝̖̺̹̤̠̙̯̭͚͔̥̺̞̰͕͓̺̙͉͈̠͍̣̩͖̪̳̘͗̂̂͗̽̄͐̊͛̑̈́̍́̄͑͆̾͂̈́̏̀̾̓̋̔̊̌̔̅̂̀̍̌̿͐́̑̊̿͛͗̽̾̈͋̀͛̄̀͛͑̉̈̚̕͘͘͘̕͜͜͠͝͝͠͝ͅ ̸̧̢̡̧̧̧̛̛̛̛͕͈͔̜̣̦͇̥̦̟̖͈̣͙̖͓̤͔̮̙̳̰̜̫͙̞͈̭̖̥̟͓͇͙̠̼̳̠͎͙̱̹̱̦̯̮̩͉̺̺̪̤͔̻͇͓͍̟́̿̑̊̈́̔̒̅͋̾̓̉̈́̑̊͑̒̋̈́͂̅̓̀̓̾́̓̌͆̈́̀̓̃͌̍͂͒́̊͛̾̔̑́͑̃̓̓̒̉͐̈́͋̈́͗̄̆̂͆̌͆̈́̉̌̋̉̇̈́̌͌́͛͂͒͌̿͊̂͘͘͘̚̕͜͝͝͠͝͝ͅͅM̵̢̧̡̨̡̡̢̧̢̡̧̧̛̘̗̙̫̬̟̠͚̭̻͖̞̩͚̘̜̤̫̙̗͙̪͈̳̬̪͙̤̬̞̝̥̮͈̗̻͓̬̹̱̟̰͎̯̞̺͍͇̠̲̯͚̬̙̼͈͍̰̭̭̲͉͈̭͉̝͍̥̩̩̱̱̥͍̮̠͉̗̖̩͕̔̍̏̌̾̍̏̌̎̐̍̈̐͊̿͆͛̿̆̂͊͆͋̋̍́͊̎̓̀͒̆̀̈̆̈́̋̐́̎͘̚̚̚͘͠͠ͅͅĘ̶̧͚̼͉͎̰̝̺̳̝̠͚̗̺͖̫̗̫̭̩̝͖͓̠̰͉̦̻̰̹̱̖̭̣̹̘̩̀̅͂͒̊͋̔͑̀̏͐͂̈́̓̓̔́̆̀́̎͗͑͌̓͛̃̅̅͑̅̓̊͒̃͛͛̈͋̾̌̋͊̾͂͊̋͆͗̽̏̑͒̄̈̓̆͋̄͗̀͆̏̓̀̈́͐̇́͌͐̏̊̍͂́͂̅͂̈̏̿̆̑͐̽̾̉͛͐̚̚͘͠͝͝͠͝͝͠͠ͅͅ ̴̡̢̨̧̧̡̧̨̟͖͕̥̮̗͇̲̰̤̭̭̺̬͕͙̼̰̻̰̮͖̦̤̥̞̮̝̫̩̠̠͍̱͉̰̜̗͇̜̯̰͍͕̠̝͖͇̗͔̠̙̣̦̭͕̮̯͕͓͓͓̠̩͓̺͉̘̘̬͇̗̜̰̲̥̣͚̳͇̬͙̜̳̦̦͉̎̿̓̇̀̆̄̉̄͑̓͐̍̇̆́̈̄̽͊͆͆͒̆̈́̊̄̅̀͌̀͌̋̆̂̎̄̓̈́̾͌̎́̎́͑̈̊̅̅̾̍͗̔̂̌̔̎̓́͒̐̍̏͂͗́̌̄̊̀͋̓́̃̍̏̇̈́̄̉̆̀̋̚̕̕͘̚̕̚̚͜͠͝͠͝͝͝͝Ą̶̢̢̨̡̢̡̢̛̛̛̛͙̖͖̠̼̬͍̺̤̰̣͓̦̺͕̞̲͙̺̩̥̺̭͈̻̱̳̲͈̙͙͙̹̳̬̺͎̰̝̠̞̪̻̘̩̩͖̞͍̈͗͊̓̋̂̑̍̏͒̎̑͋̒̀͌̉͒̏̂̑̈́̒̅͆̄́̈͂̾̒̀͛̈́̊͋̈́̑̿̇̿͒́͊̍́̋̔͋̀͆̔̾̉̀̽̽͊́̌̍̄̀̇́͆̿̊͒̄̒̑͑́̕̚̚̕̚͜͜͜͠͝͠͠͠ͅͅͅ ̸̨̛͈̲̹̺̹̥͇͉̫͖̪̣͔̱̜̮͙̳̝̙͇̫͇̠͉̤̞̠̼̆̒̂̓̓̈́̉͋̎̔͐͆͑́͗̎̾̃̀̈́̀́͐̈̀̀́͒̾͛̀̐͑͑̽̂͐́̚̕͝͝͝͝͝§̵̡̧̨̨̨̡̡̡̢̡͉̪̣̣͚̹̣̜̣͉͚͕͖͚̼̻̤̠͖̙̳͇̹̞̦̭͕̲̝̼̝̼̭̝̮̣̳̬̘̼͍̝͇͓̠͙͓̟̬̤̹͓͕͉̠͓̝̻̌̍̿̂͆̎̇̂̋͌́̈́͋̇̈͛̂̓̒̌͐̋̉̅̋̾̌̃̇͊͌̄̄̇̇̆̽̊͑̅̑́͛̈̓̑̏̃̒͐̈́͑̚̚͘̕̕͘͝͝͝͝ͅͅ†̵̢̢̢̡̡̛̳̹̰̞̟͓̣̭̮̤̦͈͙̤͓̠̦̳̥̳͖̘̻̙̥͚̬̱͖̥̩̗͕̟̩͖̝̼̳̳̭͖̠̰̫̦̱̫̱̜̤̘̜̰͍̳̹̖̙̫̻̳̿̌̊͜͜͠R̸̨̧̢̧̢̧̡̢̧̬̰̥̦̘̠̱̲̩̝̙̼̜̦͉͔̝͚͔̮̱͍͇̠̱̭̞̘͙͎͖͔̟̪̻̗̠͇̲͙̙̮̪̖̯̟̝̠̙̋̎͐͌͛̈̎̓̂̐̂̀̃̓͒̀́̃̇̐̽͑̈̏̀̉̐̔̀̂̂͑͗̇̒̅̽̈̚̚͘͝͝͝͝ͅÄ̴̢͎̿̋̓̈́̐̅̚͘͜͠¥̷̧̢̢̧̛̛̛̛̛̣̺̜͎̘͓̝̳̝̞̺̫͓̖̥̖̲̣̪̦͖͕̬̱̹͕̤͚͎̹̮͚̮̟̞̗͚͈̪̼̘͇̗͙̻̩̱̜͇̮̖͇̝̞̣͔̠͌̀̓̓̓͆̋̊̊̋́̂̐̍̏̃͋̃̅̎̿̏̅̿̑́̈́̀͗̓͆́̎̓̄̈̅̒̎̃͛͋̎͐͐̒͂̑̌̈̈́̿̐͒̌͋̐̇̌̃̉͌̀̅͑́̀͂̄̈́̾̈́́͊̒̒͐̀͊͌̿̇̑̚͘̕̚̚͜͜͠͝͝͝͝ͅͅͅ ̶̧̢̢̢̨̛̛͚͚̟̰̠̲͎̥̻̰̘͎͔̳͚̥̻̬̻͍͕̥̝̱̤̰̖̭̭̗̹̥̦̟͈͚͔͎͇͚͓͉͕͙̰̩̳̪͕̮̜̖̰̟̦̹̳͚̦̩̯̰̣̈̿̅̋͛̈́̇̔̆̀̊͂͒͑̔̈̋̅͐̉̂̍͐̾̊̆̄̃͐̓̈́̽̎̇̉̈́̇̊̌̾͐̑̓̈́̀͆̒̍̄̈́̄͆̂̽̉̂̎̉͑̄͂̏́͒̄͆̐̔̽̈́̑͐͗͐͌̈̈́̈͊́͆̐͊͘͘̚̕̚͜͠͝͝͝͝͝͠ͅͅþ̸̨̢̧̡̨̧̧̨̛̦͓̫̤͍͎̻͔͉͓͚̯̠͓̤̯͕͈͍͎̯̱̳͇͖͔͕̜̞̠͙̲̳͖͙̖̺͔̗̖͖̥̩͇̱͚̲̟̪̖͙̙͙̥͔͉͖̥͉̯̝̗̜̗̤̇̊̈̂̎͒̊͌̉̊͊̅͊͑̎̌̌̿̀͑̋̇̒̚͘͘͜͜͝͠ͅͅǪ̸̢̡̧̢̢̧̧̧̧͓͔̙̘͖͉͈̗̜̲̺̲̪̮̠̰̭̜̯̙̰̫̟̩̹̫̱͖̲͚̠͖̣̝̞̠͇͎̝̺̟̰̠͇̙̞̯̞̤̭̬̞͈͈̯̰̙̠̈̽̈́͗̇̀̈́͊̊͑̈́̌́͊͛̀̀̋̕͜͜͜͝͝͝ͅͅͅÌ̷̡̡̢̢̨̛͖̠̥͔̠͎̘̫̤̗̤͍̩͔̲̜̹͙̼̯̭̺̖̩͖͈͓̫̦͉͈̜͉̤͕̪̦̩͇͓͔̥̣̯͍̙̗̞̱͍̟͕͔̹͖̜̬̘͇̹͚͕̗̻̥̤͉̠̣̤͎̝̥̰̑̿̓͐̇̇̃̊̈́̍̍̈͆̂͐̐̆̒͗̄̄̐͊͌̒͂̌̉̀̒̋͑̾̄̐̈́͆̆̀̔́̏̐̆̆̕̚̚͝͠͝͠ͅͅñ̴̠͙͍̯̱̞̫̩̘̱̞̝͖͎̲̻̣͚̺̟̳̥̭̳͙̞̥̗̭͕̰̫̗̀̈́́͒̀͊͗͐̋̀̍͆͌̀͒̈́̾̍̇̿͌͗̈̀̋̉̈́̇̆̊̊̄͑̓̐̾̈́̀̂̀̕͘̚͝ͅͅͅͅ†̸̢̛̛͈̙̤̭̩̱̺̬̻̺̖͍̙̣͇͌́̇́̉̍̇̃̒͋̌̀̒́͑̄͒̈́͌̾̐̎̉̇͒̔͂́͗̀̍́̓͐̒̅̐̉̔͆̄̾́̂͌̊̒̓͋̎͛̐̋̔̑̂̽̚̚͠͠͠͝͝͝͝Ę̸̨̛͇̗̬̭͔̭͕̳̜̫̜̟̝̪̯̲̩̠͕͙̝͓̤̩̝̪̘̘̪̥͔̠͔̘̳͇͓͖͓̗͈͙̣̭̳̬͇̱̱͖̯̦͙̳̞̰͈̟͓̼̯̣͉̖͈̀̎͐́̀͌͗̔̓͆̓̾͛̃̐̂͒̈̈́̀͌͐͛͑͛͋̽̓̔̈̊̽̔̒͐́̔͐̽͌͒̌̃̀͐͌͑̎̂̔̎̏̏́͋̇̑́͂̀̀̿̆̈͒̃̎̌̓͗̽̄́̀͊̏̑̂̔̃̃͑̃̃͂͊̌̏͌̀͘̕̕̚͘͜͜͝͝͝͝͝ͅR̷̨̡̨̛̤̻̺̲̥͉̬͍̳̤͙̩̱̯̲͚̰̣͍̺̝̟̣̼͈̥͕͇̦̙͇͚̤̺̰͇̽͌͂͌͛̐̿̎̈́̌̆̀̂̓͌͑̏̄̐̽̂̂̆͛͌̃̒͋̄̌͌̈́͌͋̉̈́͆͂̎̈̑̋̾̀̋̒͒͗̾́͌͐̃͒̌̚͜͠͠͠͝

    Visit original content creator repository https://github.com/Eugeny/rust-sinner
  • clock

    Visit original content creator repository
    https://github.com/0xgirish/clock

  • telegram.email.notify

    Message text transformation for @EmailGateBot in Telegram Messenger

    GitHub Workflow Status GitHub Workflow Status Codacy Badge Codacy Badge

    In Russian

    @EmailGateBot allows messaging to channels and groups of Telegram by emailing to the special mailbox.

    You can automatically transform text of messages for emails from the whitelist of the chat. To do this, you need to deploy a web server on the Internet that accepts POST requests at a permanent address. A request to this address should not require authorization.

    @EmailGateBot sends POST requests with data in the request body (the data is transmitted exactly in the request body, and not as the value of some form field). The data is UTF-8 encoded text and has the following format.

    The first line contains the subject field of the email received by the bot and a line feed. The following lines contain the body of the email, including HTML markup.

    Your program should return a response with code 200 and the header ‘Content-Type=text/plain’. The text for publication in the Telegram chat should be contained in the response body.

    If your program returns a response code other than 200, then @EmailGateBot will ignore your reply and apply its standard rules for converting the contents of the received email for publication on Telegram.

    This project is an implementation of such a conversion for mailing lists of some popular resources. The project is written in python/flask and is intended to be deployed to the Google Cloud Platform AppEngine Standard Environment.

    The live version is located here.

    Visit original content creator repository https://github.com/vb64/telegram.email.notify
  • Vapor-Authenticator

    Vapor – Desktop Authenticator for Steam


    Table of Contents
    1. About
    2. Getting Started
    3. Roadmap
    4. Contributing
    5. Contact

    About

    Vapor is a 3rd party open-source authenticator app for Steam, operating as a Desktop application to allow for players who don’t have access to a smartphone to install the Steam Mobile Authenticator to be able to use Steam and trade video game items on the platform with minimal limitations.

    You don’t have to use the app as your authenticator! There are several features that can be utilised without replacing your old mobile or device authenticator, including accessing web sessions logged in as any of your accounts at the click of a button.

    Because the project is open-source utilising APIs offered by Steam, additional features can be added in by the community to build an application that not only provides what the current existing mobile authenticator app offers but more to help Steam traders, gamers and players.

    Features

    General

    • Use the app as your main device authenticator
    • Generate Steam Guard codes to login to different websites using your Steam account
    • Revoke the authenticator with little hassle
    • View and switch between all of your accounts
    • Access proxy Steamcommunity.com web sessions as your other accounts
    • View your Steam profile in a jiffy
    • Login to the app passwordless via OAuth using just a previous username

    Trading

    • See all your trades via web session
    • View your trade confirmations
    • Confirm or cancel confirmations from the app

    Gaming

    • Idle all of your games at the click of a button
    • Send and receive messages to your friends in an instant via Steam Web Chat as any saved account

    Inventory Management

    • View your in-game inventory for TF2, CS:GO, Dota2 and other games at the click of a button

    Technicals

    Vapor is developed in TypeScript using ElectronJS to produce the application for desktop. ReactJS and TailwindCSS has been integrated into the project to make frontend development easier.

    There are several tools including Babel to compile TypeScript into plain JavaScript and Webpack to build the project into a development build that can be ran and tested locally.

    Getting Started

    Installation

    Stable

    You can download your system’s respective installer (.exe for Windows, .dmg for MacOSX, and .AppImage for Linux) for the latest stable version in Releases.

    You can always install the latest version of the application here to replace your current version. Download the installer, delete your shortcut of the application and load the installer.

    Unless it is stated explicitly that your previous config file containing account information is incompatible with the latest version (which a converter will be provided for), you will be able to access your accounts as normal after installation.

    Development

    You will need node and npm to run this project as a developer and build it from source.

    1. Clone or download this project from GitHub and cd into the project directory. This will install all necessary dependencies, including dev-dependencies, to allow you to build the project alongside install developer tools to make development easier.
    2. Run npm start to build and bootup the app to ensure that it is working for you. You can exit using Ctrl + C once you have finished testing it.

    Roadmap

    These planned features have been sourced from discussions with users and communities. Some may also be features that are missing from Vapor that exist in the current version of the Steam Mobile Authenticator app.

    * – Provided by the existing Steam Mobile Authenticator App

    General

    • Export your secrets for other applications e.g trading bots
    • Display all new Steam account notifications e.g gifts, new items *
    • Remove logged accounts from the authenticator

    Trading

    • Notify you of new trades via a desktop notification
    • Option to auto-accept all (incoming) trade confirmations
    • Option to auto-accept all (incoming) market confirmations

    Contributing

    You can read details on how to contribute here.

    Contact

    You can contact me on Steam here.

    Visit original content creator repository https://github.com/HilliamT/Vapor-Authenticator
  • lang-modeling

    langauge modeling with RNNs in tensorflow

    I built it with 3 stacked GRUs ..text8 as dataset for word level language model .. aslo tried character level language modeling on linux source code 😀 by appending some of linux c files and results are so fun 😀

    I included only the trained model for linux source code in this repository .. I had 6 more models working on character level(linux source code and shakespere books) with embedding and one hot encoding aslo word level(on text8)

    charachers/words are generated by sampling (probabilistic sampling not greedy)

    How to play ??

    just run tf_my_lm_player.py and this will generate some c-like code

    Example generation for “#inclu” seed 😀

    de <linux/string.h>
    #include <linux/uacdir.h>
    #include <linux/mm.h>
    #include <linux/module.h>
    #include <linux/sched/names.h>
    #include <linux/slab.h>
    #include <linux/slab.h>
    #include <linux/partitull.h>
    #include <linux/slab.h>
    
    

    Example generation for random seed

    
    static void pipe_lock(struct pipe_inode_info *pipe)
    {
    	struct pipe_inodeinfo *ipimap = null;
    
    	inode = lock_inode(inode);
    	status = file_mapping_tree_lock(&fl->fl_file, fl);
    	list_for_each_entry(&fl->fl_list, &conf_lock->lock, fl_list)) {
    		struct page *page;
    		int rc = 0;
    
    		/* copy the page of the page */
    		page = local_page_address(page);
    
    		if (pages) {
    			page = find_pages_per_page(inode);
    			if (page == null)
    				goto out_fail;
    			len = page_size;
    			page = false;
    		}
    	} else {
    		/*
    		 * if we've active a page to be a page of a single page and the state of the
    		 * request as we're not a possible to avoid any operation the one of
    		 * the policy.  if we don't want to specify
    		 * a no longer the non-locked page is allocated and we are not
    		 * a complete and
    		 * the page is a pointer to the leaf page and the page is a caller and the new page
    		 * and the page is already already allocated and we're already the lock.
    		 */
    		if (page->index) {
    			/* if we can't allocate an extended page in this leaf. */
    			page->index = page_size;
    			put_page(page);
    			ret = -einval;
    			goto out;
    		}
    		page->mapping->a_ops = &pagelocked;
    		page->mapping = page;
    		put_page(page);
    		return -enomem;
    	}
    
    	if (!page) {
    		page = falloc_extent_map();
    		return -enoent;
    
    		/* set the page */
    		if (page != pmd)
    			ret = -eio;
    
    		if (rc)
    			return rc;
    		len = page_size(page);
    		locked_page->index =
    			length - 1;
    		len = length;
    	}
    
    	/* fill the new page in the parent page */
    	page = page_size(page);
    	page = page_address(page);
    	put_page(page);
    	page->mapping->host = file;
    	page->mapping->host = falloc_fl;
    	ret = falloc_fl_put(page);
    	if (ret < 0)
    		goto out;
    
    	/* for a pointer to the length. */
    	pool = pos;
    	inode->i_old_pages[i] = page;
    	if (page == null) {
    		page->index++;
    		ret = -enomem;
    		goto out;
    	}
    
    	/* find a newly allocated bytes of a node */
    	if (pos >= page_size) {
    		/* note that we can't alled the page on the page of the page */
    		page = null;
    		len = page_size;
    
    		/*
    		 * if we can't allocate the page and we already have the page
    		 * and allowed the page and the non-loop is not already been
    		 * a caller and the page is not allowed to allocate the offset
    		 */
    		inode = old;
    		if (!pageuptodate(page)) {
    			/*
    			 * insert any of transaction or a set of the length of a page of the length.  in the
    			 * extent is a page is a part of a non-exact extent to the page and we can point
    			 * to the non-extent of an entry.  the page is not already allowed to be
    			 * a possible to a partial page as a new entry.
    			 */
    			if (!(page->index == page->index + 1)) {
    				page = false;
    				return err_ptr(-enomem, page_start, end);
    			}
    			if (page == null) {
    				page = null;
    				end_page_writeback(page);
    				ret = page_shift_pages(inode->i_mapping);
    				break;
    			}
    			if (pages[i] == null)
    				return -eio;
    			else if (!page)
    				return;
    			page = null;
    		}
    		if (!pageuptodate(page))
    			goto out;
    		if (page == null) {
    			page = false;
    			ret = -enomem;
    			page = null;
    			goto out;
    		}
    		extent_start = len - 1;
    	}
    
    	/* if we are a page buffer */
    	if (buffer_uptodate(page)) {
    		/*
    		 * if we've already a page before the page isn't allocated to truncate the page
    		 * and real the page.
    		 */
    		page = find_address(page, page_size);
    	}
    
    	/* if we are a page that we've already a pointer to this page in the buffer.
    	 */
    	if (page->index < page_size) {
    		page = find_page_container_add(page);
    		if (page != page)
    			return -einval;
    	}
    	return 0;
    }
    
    

    Resources

    Visit original content creator repository
    https://github.com/mohammed-elkomy/lang-modeling

  • pluggit

    Pluggit

    Home Assistant integration for Pluggit ventilation units

    Note

    This integration is based on the Dantherm integration 👈, as Pluggit and Dantherm ventilation units appear to share the same controller hardware. To avoid maintaining the code in two separate places, most of the code in this repository is copied from the Dantherm integration with each release.

    Buy Me A Coffee

    ⚠️ Compatibility Notice

    This custom integration requires:

    • Home Assistant version 2025.1.0 or newer

    Only support for Modbus over TCP/IP.

    Known supported units:

    • AP190
    • AP310

    The listed units are known to work with this integration. Basically, all units compatible with the Dantherm Residential or Pluggit iFlow apps should work with the integration as well.

    Note

    If you have a model not listed and are using this integration, please let me know by posting here. Make sure to include both the model name and the unit type number.
    The number can be found in the Device Info section on the integration page; if the unit is not recognized, it will be listed as “Unknown” followed by the number.

    Controls and sensors

    Buttons Entities

    Entity Description
    alarm_reset Clears the active alarm and dismis the alarm notification
    filter_reset Resets the filter remain timer and dismis the alarm notification

    Calendar Entity

    Entity Description
    calendar Controls scheduled operations based on Home Assistant calendar events

    Cover Entity

    Entity Description
    bypass_damper Indicates and controls the manual bypass state of the bypass damper [1]

    Number Entities

    Entity Description
    boost_mode_timeout Sets the duration for Boost Mode before it automatically turns off [3]
    bypass_minimum_temperature Minimum outdoor temperature allowed for bypass damper to open [2][5]
    bypass_maximum_temperature Maximum outdoor temperature allowed for bypass damper to open [2][5]
    eco_mode_timeout Sets the duration for Eco Mode before it automatically deactivates [3]
    filter_lifetime Expected lifetime of the filter before triggering a replacement notification [2]
    home_mode_timeout Sets how long Home Mode should remain active after being triggered [3]
    manual_bypass_duration Duration for which manual bypass remains active after user activation [1][2][5]

    Select Entities

    Entity Description
    boost_operation_selection Defines which mode to apply when Boost Mode is triggered [3]
    default_operation_selection Fallback mode used when no other mode is active
    eco_operation_selection Defines which mode to apply when Eco Mode is triggered [3]
    fan_level_selection Selects the current fan level (Level 0 to Level 4). Level 0 and Level 4 will timeout after a fixed period.
    home_operation_selection Defines which mode to apply when Home Mode is triggered [3]
    operation_selection Selects the current mode of operation (Standby, Automatic, Manual, Week Program, Away Mode, Summer Mode, Fireplace Mode and Night Mode). Night Mode is display only. Standby and Fireplace Mode will timeout after a fixed period.
    week_program_selection Selects the active predefined week program (Week Program 1 to Week Program 11). Week Program 11 can be user defined but not through the integration. [2]

    Sensor Entities

    Entity Description
    air_quality Measures air quality if the unit is equipped with a VOC or CO₂ sensor [1]
    air_quality_level Indicates the qualitative level of air quality (Clean, Polluted, etc.) [2]
    alarm Reports active alarms such as fan or temperature alarms
    exhaust_temperature Temperature of indoor air being exhausted after heat recovery
    extract_temperature Temperature of indoor air being pulled out for heat recovery
    fan_level Current fan level (Level 0 to Level 4)
    fan1_speed Actual RPM of fan 1 [2]
    fan2_speed Actual RPM of fan 2 [2]
    filter_remain Remaining filter life in days
    filter_remain_level Qualitative status of remaining filter life (e.g. Good, Replace) [2]
    humidity Indoor relative humidity from internal sensor [1]
    humidity_level Qualitative level of humidity (e.g. Dry, Normal, Humid) [2]
    adaptive_state Shows which adaptive mode (Home, Eco, Boost) is currently active [4]
    internal_preheater_dutycycle Percentage of power used by the internal electric preheater [1][2]
    operation_mode Current system mode: Automatic, Manual, Week Program, etc.
    outdoor_temperature Temperature of fresh outdoor air being pulled in from outside the home
    room_temperature Room air temperature from the Pluggit HRC/Pluggit APRC remote [1][2]
    supply_temperature Temperature of the supply air delivered to the home
    work_time Total operational runtime of the unit [2]

    Switch Entities

    Entity Description
    away_mode Enables or disables Away Mode
    boost_mode Enables or disables Boost Mode [3]
    disable_bypass Forces the bypass damper to remain closed [2]
    eco_mode Enables or disables Eco Mode [3]
    fireplace_mode Enables Fireplace Mode, increases supply air to compensate for fireplace draft
    home_mode Enables or disables Home Mode [3]
    manual_bypass_mode Manually activates bypass regardless of conditions [1]
    night_mode Enables or disables Night Mode [2]
    sensor_filtering Enables or disables sensor value filtering for stability [2]
    summer_mode Enables or disables Summer Mode

    Text Entities

    Entity Description
    night_mode_end_time Sets the end time for Night Mode [2]
    night_mode_start_time Sets the start time for Night Mode [2]

    Notes

    [1] The entity may not install due to lack of support or installation in the particular unit.
    [2] The entity is disabled by default.
    [3] The entity will be enabled or disabled depending on whether the corresponding adaptive trigger is configured.
    [4] The entity can only be enabled if any of the adaptive triggers are configured.
    [5] The entity may not install due to firmware limitation.

    Strikethrough is a work in progress, planned for version 0.5.0.

    Installation

    Installation via HACS (Home Assistant Community Store)

    1. Ensure you have HACS installed and configured in your Home Assistant instance.
    2. Open the HACS (Home Assistant Community Store) by clicking HACS in the side menu.
    3. Click on Integrations and then click the Explore & Download Repositories button.
    4. Search for “Pluggit” in the search bar.
    5. Locate the “Pluggit Integration” repository and click on it.
    6. Click the Install button.
    7. Once installed, restart your Home Assistant instance.

    Manual Installation

    1. Navigate to your Home Assistant configuration directory.
      • For most installations, this will be ‘/config/’.
    2. Inside the configuration directory, create a new folder named ‘custom_components’ if it does not already exist.
    3. Inside the ‘custom_components’ folder, create a new folder named ‘pluggit’.
    4. Download the latest release of the Pluggit integration from the releases page into the ‘custom_components/pluggit’ directory:
    5. Once the files are in place, restart your Home Assistant instance.

    Configuration

    After installation, add the Pluggit integration to your Home Assistant configuration.

    1. In Home Assistant, go to Configuration > Integrations.
    2. Click the + button to add a new integration.
    3. Search for “Pluggit” and select it from the list of available integrations.
    4. Follow the on-screen instructions to complete the integration setup.

    Skærmbillede 2024-05-04 090018 Skærmbillede 2024-05-04 090125

    Support

    You can open issues directly on this repository. To keep discussions centralized, please refer to the Dantherm Integration here.

    Languages

    Currently supported languages:

    Danish, Dutch, English, German and French.

    Note

    Want to help translate? Grab a language file on GitHub here and post it here. You are also welcome to submit a PR.

    Screenshots

    Skærmbillede fra 2025-02-09 15-49-04

    Skærmbillede fra 2025-02-09 15-26-39 Skærmbillede fra 2025-02-09 15-27-48

    Skærmbillede fra 2025-02-09 15-28-23 Skærmbillede fra 2025-02-09 15-28-58

    Skærmbillede fra 2025-02-09 15-31-03

    Note

    The HAC module functions are currently unsupported due to limited testing possibilities. If support for these functions are desired, please contact me for potential collaborative efforts to provide the support.

    Examples

    Picture-elements card

    new The picture elements card has been updated with fresh images and options to include humidity and air quality sensors with changing level icons (2025-6-29).

    This picture-elements card provides a dynamic and intuitive interface for monitoring and controlling your Pluggit ventilation unit. Designed to resemble the Pluggit app, it visually adapts based on the unit’s bypass state while displaying key real-time data:

    • Alarms – Stay alerted to system issues.
    • Filter Remaining Level – Easily check when filter replacement is needed.
    • Ventilation Temperatures – View four key temperature readings: Supply, Extract, Outdoor, and Exhaust.
    • Humidity Level – Monitor indoor humidity for optimal air quality.
    • Air Quality – Monitor indoor air quality.

    Clicking on any displayed entity allows you to adjust its state or explore detailed history graphs for deeper insights.

    Skærmbillede 2025-06-30 kl  05 39 01 Skærmbillede 29-06-2025 kl  07 42 02 AM Skærmbillede 29-06-2025 kl  07 45 12 AM Skærmbillede 29-06-2025 kl  08 52 02 AM

    The details for the above picture-elements card 👈 Click to open

    To integrate this into your dashboard, begin by downloading and extracting this zip file. Copy the contained files into the “www” folder within your configuration directory on Home Assistant. You can use the Samba share add-on, the upload feature in the Studio Code Server add-on, or other preferred methods.

    Next, insert the following code into your dashboard. If your Home Assistant setup uses a language other than English, make sure to modify the entity names in the code accordingly. You also need to enable the filter_remain_level, humidity_level and air_quality_level sensors if these options are included.

    The code

    type: picture-elements
    image: /local/pluggit1.png
    elements:
      - type: image
        entity: sensor.pluggit_filter_remain_level
        state_image:
          "0": /local/pluggit4.png
          "1": /local/pluggit5.png
          "2": /local/pluggit6.png
          "3": /local/pluggit7.png
        style:
          left: 59.5%
          top: 50%
          width: 20.04%
        tap_action:
          action: none
      - type: conditional
        conditions:
          - entity: sensor.pluggit_operation_mode
            state_not: "6"
        elements:
          - type: image
            entity: cover.pluggit_bypass_damper
            state_image:
              closed: /local/pluggit2.png
              closing: /local/pluggit2.png
              open: /local/pluggit3.png
              opening: /local/pluggit3.png
            style:
              left: 59.4%
              top: 74.35%
              width: 79.66%
            tap_action:
              action: more-info
          - type: conditional
            conditions:
              - entity: cover.pluggit_bypass_damper
                state:
                  - closed
                  - closing
            elements:
              - type: state-label
                entity: sensor.pluggit_outdoor_temperature
                style:
                  top: 66%
                  left: 83%
              - type: state-label
                entity: sensor.pluggit_extract_temperature
                style:
                  top: 66%
                  left: 35%
              - type: state-label
                entity: sensor.pluggit_exhaust_temperature
                style:
                  top: 83%
                  left: 83%
              - type: state-label
                entity: sensor.pluggit_supply_temperature
                style:
                  top: 83%
                  left: 35%
          - type: conditional
            conditions:
              - entity: cover.pluggit_bypass_damper
                state:
                  - open
                  - opening
            elements:
              - type: state-label
                entity: sensor.pluggit_extract_temperature
                style:
                  top: 66%
                  left: 35%
              - type: state-label
                entity: sensor.pluggit_outdoor_temperature
                style:
                  top: 83%
                  left: 83%
      - type: conditional
        conditions:
          - entity: sensor.pluggit_operation_mode
            state: "6"
        elements:
          - type: image
            image: /local/pluggit8.png
            style:
              left: 59.4%
              top: 74.35%
              width: 79.66%
            tap_action:
              action: none
          - type: state-label
            entity: sensor.pluggit_extract_temperature
            style:
              top: 65.5%
              left: 35%
      - type: conditional
        conditions:
          - entity: sensor.pluggit_alarm
            state_not: "0"
        elements:
          - type: state-label
            entity: sensor.pluggit_alarm
            style:
              top: 15%
              left: 50%
              width: 100%
              font-weight: bold
              text-align: center
              color: white
              background-color: red
              opacity: 70%
      - type: state-label
        entity: select.pluggit_operation_selection
        style:
          top: 47%
          left: 25.5%
          # font-size: 125%
      - type: state-label
        entity: select.pluggit_fan_selection
        style:
          top: 29%
          left: 60%
          # font-size: 125%
          transform: translate(0%,-50%)
    #  - type: image
    #    entity: sensor.pluggit_humidity_level
    #    state_image:
    #      "0": /local/pluggit9.png
    #      "1": /local/pluggit10.png
    #      "2": /local/pluggit11.png
    #      "3": /local/pluggit12.png
    #    style:
    #      top: 29%
    #      left: 16%
    #      width: 3.76%
    #    tap_action:
    #      action: none
    #  - type: state-label
    #    entity: sensor.pluggit_humidity
    #    style:
    #      top: 29%
    #      left: 18%
    #      # font-size: 125%
    #      transform: translate(0%,-50%)
    #  - type: image
    #    entity: sensor.pluggit_air_quality_level
    #    state_image:
    #      "0": /local/pluggit13.png
    #      "1": /local/pluggit14.png
    #      "2": /local/pluggit15.png
    #      "3": /local/pluggit16.png
    #    style:
    #      top: 29%
    #      left: 36%
    #      width: 5.45%
    #    tap_action:
    #      action: none
    #  - type: state-label
    #    entity: sensor.pluggit_air_quality
    #    style:
    #      top: 29%
    #      left: 39%
    #      # font-size: 125%
    #      transform: translate(0%,-50%)
    

    Dashboard Badges

    Here are some examples of badges added to the dashboard. The pop-up that appears when clicking on a badge will vary depending on the selected entities, either displaying information or enabling manipulation of the Pluggit unit.

    Skærmbillede badge example

    Apex-chart

    Skærmbillede 2025-06-23 092901

    The details for the above Apex-chart card (Can be found on HACS) 👈 Click to open
    type: custom:apexcharts-card
    update_interval: 5min
    apex_config:
      stroke:
        width: 2
        curve: smooth
    graph_span: 24h
    series:
      - entity: sensor.pluggit_extract_temperature
        name: Extract Temperature
        extend_to: false
        show:
          extremas: true
          legend_value: false
        group_by:
          duration: 5min
          func: avg
      - entity: sensor.pluggit_outdoor_temperature
        name: Outdoor Temperature
        extend_to: false
        show:
          extremas: true
          legend_value: false
        group_by:
          duration: 5min
          func: avg
      - entity: sensor.pluggit_exhaust_temperature
        name: Exhaust Temperature
        extend_to: false
        show:
          legend_value: false
        group_by:
          duration: 5min
          func: avg
      - entity: sensor.pluggit_supply_temperature
        name: Supply Temperature
        extend_to: false
        show:
          legend_value: false
        group_by:
          duration: 5min
          func: avg
    

    Sensor Filtering

    To improve the stability and reliability of sensor readings, the integration now supports sensor filtering for key environmental data collected from the Pluggit unit. This filtering mechanism is applied to the following sensors:

    • Humidity
    • Air Quality
    • Exhaust Temperature
    • Extract Temperature
    • Supply Temperature
    • Outdoor Temperature
    • Room Temperature

    Control via Home Assistant Switch

    The filtering feature can be enabled or disabled via the “Sensor Filtering” switch entity. By default, the filtering is disabled, ensuring the system behaves as it did previously. When the switch is enabled, the filtering logic described below will be applied.

    How It Works

    Each sensor is equipped with a sliding history buffer, storing the last 5 readings. The filter applies two techniques:

    1. Initialization Smoothing
      For the first few readings (up to 5), the filter calculates a simple average. This helps the sensor start off with a stable baseline, preventing a single bad initial reading from influencing the system.

    2. Spike Filtering
      After initialization, every new reading is compared to a rolling average of the last 5 readings.
      If the new reading changes more than a defined threshold (max_change) compared to the rolling average, the spike is rejected, and the system uses the current rolling average instead.

    Individual Thresholds per Sensor

    Each sensor type has a predefined maximum allowed change per reading:

    Sensor Max Change
    Humidity 5% RH
    Air Quality 50 PPM
    Temperatures 2°C

    This ensures the filtering logic fits the natural dynamics of each sensor type.

    This feature was inspired by issue #68, reported by a community user.

    Actions

    Using the “Pluggit: Set State” and “Pluggit: Set configuration” Actions

    The Pluggit: Set state action allows you to control the state of your Pluggit ventilation unit directly from a Home Assistant automation. This action provides a wide range of options to customize the operation of your unit, making it suitable for various scenarios.

    Steps to Use the “Set State” Action

    1. Create a New Automation:

      • Navigate to Settings > Automations & Scenes.
      • Click on Add Automation and select Start with an empty automation.
    2. Configure a Trigger:

      • Add a trigger that fits your use case. For example:
        • A time-based trigger to schedule changes.
        • A sensor-based trigger to react to environmental changes.
          • Air Quality Sensor: Trigger when CO2 levels exceed a threshold, e.g., 1000 ppm.
          • Humidity Sensor: Trigger when humidity exceeds, e.g., 70%.
          • Window Sensor: Trigger when a window opens.
          • Cooker Hood: Trigger when the smart plug detects power usage above a threshold.
    3. Add the “Pluggit: Set State” Action:

      • Under the Actions section, click Add Action.
      • Search for Pluggit: Set state in the action picker and select it.
    4. Configure the Action:

      • Use the options provided to control the Pluggit ventilation unit:
        • Targets: Choose the area, device, or entity to apply the action.
        • Operation Selection: Set the desired operating mode (e.g., Standby, Automatic, Manual, or Week Program).
        • Fan Selection: Choose the desired fan level (Level 0–4).
        • Modes: Toggle special modes like:
          • Away Mode: Enable or disable away mode.
          • Summer Mode: Turn summer mode on or off.
          • Fireplace Mode: Activate fireplace mode for a limited period.
          • Manual Bypass Mode: Enable or disable manual bypass.

    Skærmbillede fra 2025-02-09 14-46-28

    1. Save the Automation:
      • Once configured, save the automation. The Pluggit unit will now respond to the specified trigger and perform the desired action.

    The Pluggit: Set configuration action allows you to adjust various configuration settings of your Pluggit device directly from Home Assistant. This action can be used in automations, scripts, or manually through the Developer Tools.

    Skærmbillede fra 2025-02-09 14-49-25

    ⏳ The following sections are a work in progress

    These features are planned for version 0.5.0. The calendar function is currently still under development.

    Integration enhancements

    The integration enhances the control of Pluggit ventilation units by introducing Boost Mode, Eco Mode, Home Mode, and a Calendar Function for advanced scheduling and automation. These features ensure efficient operation based on both schedules and various triggers, providing a comfortable and energy-efficient environment.

    Boost Mode 🚀

    Boost Mode is designed for short bursts of increased ventilation, useful after activities like cooking or showering.

    • Boost Mode Switch: This must be enabled for Boost Mode to activate.
    • Trigger-Based Activation: If Boost Mode is enabled and the Boost Mode Trigger is active, the unit switches to the Boost Operation Selection.
    • Timeout Handling: See Trigger Timeout for details on how long Boost Mode remains active after the trigger is deactivated.
    • Available Operations: Level 4, Level 3, or Level 2.

    Important
    The Pluggit unit has a built-in automatic setback from Level 4 to Level 3 after a fixed time period. This may cause Boost Mode to behave unexpectedly if Level 4 is used for longer periods.

    Eco Mode 🌱

    Eco Mode is designed to reduce fan speed under specific environmental conditions, optimizing efficiency and supporting the unit’s defrost mechanism in cold weather.

    • Eco Mode Switch: This must be enabled for Eco Mode to activate.
    • Trigger-Based Activation: If Eco Mode is enabled and the Eco Mode Trigger is active, the unit switches to the Eco Operation Selection.
    • Timeout Handling: See Trigger Timeout for details on how long Eco Mode remains active after the trigger is deactivated.
    • Available Operations: Standby and Level 1.

    Important
    The Pluggit unit has a built-in automatic setback from Standby to Level 3 after a fixed time period. This may cause Eco Mode to behave unexpectedly if Standby is used for longer periods.

    Home Mode 🏡

    Home Mode allows for automatic adjustments based on a Home Mode Trigger, ensuring efficient ventilation when you are at home.

    • Home Mode Switch: This must be enabled for Home Mode to activate.
    • Trigger-Based Activation: If Home Mode is enabled and the Home Mode Trigger is active, the unit switches to the Home Operation Selection.
    • Timeout Handling: See Trigger Timeout for details on how long Home Mode remains active after the trigger is deactivated.
    • Available Operations: Automatic, Level 3, Level 2, Level 1, or Week Program.

    Trigger Timeout ⏱️

    Each mode trigger (Boost, Eco, Home) includes a configurable timeout that defines how long the mode remains active after the trigger is deactivated.

    • Timeout Behavior: After the trigger turns off, the unit continues operating in the triggered mode for the remaining timeout period.
    • Reset on Re-trigger: If the trigger is activated again within the timeout window, the countdown restarts.
    • Automatic Revert: When the timeout expires without further trigger activity, the unit reverts to the operation mode that was active before the trigger event—unless this has been overridden by a calendar schedule.

    This mechanism ensures that temporary conditions (e.g., presence, humidity, low temperature) cause a short-term mode change without disrupting long-term schedules.

    Adaptive Triggers ⚡

    Boost, Eco, and Home Modes rely on Adaptive Triggers — binary sensors or helpers that determine when a mode should activate.

    An Adaptive Trigger can be:

    • A motion sensor (e.g., presence detection for Home Mode)
    • A humidity sensor (e.g., high humidity after a shower for Boost Mode)
    • A power sensor (e.g., detecting stove or shower fan usage)
    • An outdoor temperature sensor (e.g., reducing fan speed in cold weather for Eco Mode)
    • A custom helper combining multiple conditions

    Adaptive Triggers are configured manually in the integration options and linked to each mode individually.

    ⚠️ Note
    Only entities of type binary_sensor or input_boolean are supported as Adaptive Triggers.
    Make sure the entity returns an on or off state.

    Trigger Entity Availability 🛑

    Entities related to Boost, Eco, and Home Modes (e.g., mode switch, timeout, operation selection) are disabled by default unless a corresponding trigger is configured.

    If you manually enable these entities via Home Assistant, they will be automatically disabled again after a reload of the integration unless a valid trigger is set in the integration options.

    Configuring the integration

    How to Open the Integration Options

    To change settings such as disabling temperature unknown values, disabling notifications, or configuring adaptive triggers:

    1. Go to Home Assistant → Settings → Devices & Services → Integrations.
    2. Find the Pluggit integration in the list. Skærmbillede 23-04-2025 kl  07 04 48 AM
    3. Click the Configure button (gear icon) for your Pluggit integration instance.
    4. The options dialog will open, where you can adjust the available settings. Skærmbillede 13-07-2025 kl  07 15 56 AM

    How to Set Up an Adaptive Trigger

    1. Enter the trigger entity in the appropriate field.
      Use the field for the mode you want to configure (e.g., Boost Mode Trigger, Eco Mode Trigger, or Home Mode Trigger).
      Example values:
      binary_sensor.kitchen_motion, binary_sensor.living_room_presence, binary_sensor.outdoor_temperature_low
    2. Click Submit to save your configuration.
    3. Enable the corresponding mode in the Home Assistant UI to activate the trigger.

    Once configured, the Pluggit unit will automatically switch to the selected operation mode whenever the Adaptive Trigger becomes active. ⚡

    Disabling “Unknown” Temperatures in Bypass and Summer Mode

    To prevent temperature sensors from being set to unknown during bypass or summer mode, enable the option “Disable setting temperatures to unknown in bypass/summer modes”. When this option is enabled, temperature sensors will always report their current value, even when the device is in bypass or summer mode.

    Disabling Notifications

    To disable all persistent notifications from the Pluggit integration, enable “Disable notifications”. When this option is enabled, the integration will not send any persistent notifications to Home Assistant’s notification area.

    Calendar Function 📅

    The Calendar Function allows precise scheduling of different operation modes, providing full automation of the ventilation system.

    • Integration – Calendar Events:
      By entering an event word into the summary of a calendar event, the selected operation will take effect when the event starts, assuming it has a higher priority event words than an ongoing event. When the event ends, the system will revert to the previously active event. If no underlying event exists, the unit will revert to the Default Operation Selection.

    • Event Words: You can schedule “Level 1“, “Level 2“, “Level 3“, “Automatic“, “Away Mode“, “Night Mode“, “Boost Mode“, “Home Mode“, “Eco Mode“, and “Week Program“. These terms will be translated according to the selected language in Home Assistant, assuming your language is supported by the integration.

      • If Level 1 to Level 3 is scheduled, the unit will run in Manual mode at the selected fan level.
      • If Automatic is scheduled, the unit will operate in Demand Mode.
      • If Away Mode is scheduled, Away Mode will be enabled at the start and disabled at the end of the event.
      • If Night Mode is scheduled, Night Mode will be enabled at the start and disabled at the end of the event.
      • If Boost Mode, Home Mode, or Eco Mode is scheduled, the respective mode’s trigger will be enabled at the start and disabled at the end, allowing the unit to switch modes dynamically.
      • If Week Program is scheduled, the unit will follow the selected program in Week Program Selection.
    • Priority System: The following is the priority order for calendar scheduling:

      1. Away Mode (highest priority)
      2. Boost Mode
      3. Night Mode
      4. Home Mode
      5. Eco Mode
      6. Level 3
      7. Level 2
      8. Level 1
      9. Automatic
      10. Week Program (lowest priority)

    The available operations in Default Operation Selection are Automatic, Level 3, Level 2, Level 1, or Week Program.

    Important

    The Pluggit unit has built-in Night Mode Start Time and Night Mode End Time. Scheduling Night Mode outside of these times may not function as expected.

    These features provide seamless automation and intelligent airflow control, ensuring the ventilation system adapts dynamically to both planned schedules and real-time environmental conditions. 🚀🏡🌱📅

    Disclaimer

    The trademark “Pluggit” is owned by Pluggit GmbH.

    The trademark “Dantherm” is owned by Dantherm Group A/S.

    All product names, trademarks, and registered trademarks mentioned in this repository are the property of their respective owners.

    I am not affiliated with Pluggit or Dantherm, except as the owner of a Dantherm HCV400 P2 unit.

    The author does not guarantee the functionality of this integration and is not responsible for any damage.

    Tvalley71

    Visit original content creator repository https://github.com/Tvalley71/pluggit