code:
---
title: Information about sending patches for review
x-toc-enable: true
...

Download Libreboot from the Git repository like so:

    $ git clone https://notabug.org/libreboot/libreboot.git

You can submit your patches via
[Notabug pull requests](#how-to-submit-your-patches-via-pull-requests) or
[via mailing list](#how-to-submit-your-patches-via-mailing-list).

Information about how the Libreboot project is governed is documented in our
[general management guidelines](management.md).

Editing the website and documentation, wiki-style
-------------------------------------------------

The website and documentation is inside the `www` directory in the
[Git repository](#how-to-download-libreboot-from-the-git-repository), in
Pandoc flavoured Markdown. The website is generated into static HTML via Pandoc
with the following scripts in that directory:

- index.sh: generates the news feed (on the News section of the website)
- publish.sh: converts an .md file to an .html file
- Makefile: with calls to index.sh and publish.sh, compiles the entire
  Libreboot website

Use any standard text editor (e.g. Vim, Emacs, Nano, Gedit) to edit the files,
commit the changes and
[send patches](#how-to-submit-your-patches-via-pull-requests).

Optionally, you can install a web server (e.g. lighttpd, nginx) locally and
set the document root to the *www* directory in your local Git repository.
With this configuration, you can then generate your local version of the
website and view it by typing `localhost` in your browser's URL bar.

General guidelines for submitting patches
-----------------------------------------

We require all patches to be submitted under a free license:
<https://www.gnu.org/licenses/license-list.html>.

- GNU General Public License v3 is highly recommended
- For documentation, we require GNU Free Documentation License v1.3 or higher

*Always* declare a license on your work! Not declaring a license means that
the default, restrictive copyright laws apply, which would make your work
non-free.

GNU+Linux is generally recommended as the OS of choice, for Libreboot
development.

General code review guidelines
------------------------------

Any member of the public can
[submit a patch](#how-to-submit-your-patches-via-pull-requests).
Members with push access must *never* push directly to the master branch;
issue a Pull Request, and wait for someone else to merge. Never merge your own
work!

Your patch will be reviewed for quality assurance, and merged if accepted.

How to download Libreboot from the Git repository
-------------------------------------------------

In your terminal:

    $ git clone https://notabug.org/libreboot/libreboot.git

A new directory named `libreboot` will have been created, containing
libreboot.

How to submit your patches (via pull requests)
----------------------------------------------

Make an account on <https://notabug.org/> and navigate (while logged in) to
<https://notabug.org/libreboot/libreboot>. Click *Fork* and in your account,
you will have your own repository of Libreboot. Clone your repository, make
whatever changes you like to it and then push to your repository, in your
account on NotABug.

Now, navigate to <https://notabug.org/libreboot/libreboot/pulls> and click
*New Pull Request*.

You can submit your patches there. Alternative, you can log onto the Libreboot
IRC channel and notify the channel of which patches you want reviewed, if you
have your own Git repository with the patches.

Once you have issued a Pull Request, the Libreboot maintainers will be notified
via email. If you do not receive a fast enough response from the project, then
you could also notify the project via the #libreboot channel on Freenode.

How to submit your patches (via mailing list)
---------------------------------------------

We also have a mailing list at
[development@libreboot.org](mailto:development@libreboot.org)

Information about this mailing list, including how to subscribe, can be found
at <https://libreboot.org/lists/>.

Archives of previous discussion on this mailing list can be found at
<https://libreboot.org/pipermail/development/>.

The mailing list software in use is
[GNU Mailman](https://www.gnu.org/software/mailman/), so the way to use it is
the same as on other libre software projects.

If you prefer, you can submit patches the old-fashioned (as some may say,
proper) way by sending them to our mailing list. Code review by our
[maintainers](management.md) is done on both Notabug and on the mailing list.

Once approved, your patch will be merged in the master branch of the main Git
repository.


code:
html {
    background-color: #eee;
}

body {
    background-color: #fff;
    margin: 0 auto;
    max-width: 60em;
    padding: 0.2em 1em;
    box-shadow: 0 0 6px;
}

body {
    line-height: 1.6;
    font-family: Cantarell, sans-serif;
    font-size: 1.1em;
    color: #222;
}

pre {
    margin-left: 2.5em
}

#logo {
    width: 20%;
    float: right;
}

a {
    text-decoration: none;
    color: #22D;
}

a:hover {
    color: #008;
}

.date {
    display: block;
}

h1, h2, h3, .h:hover a {
    display: inline;
}

.h a {
    display: none;
}

license: mit


code:
---
title: Libreboot
...

[![Libreboot logo](logo/logo.svg "Canteloupe, the libreboot
mascot"){#logo}](faq.md#who-did-the-logo)

[FAQ](faq.md)                                                               --
[Download](download.md)                                                     --
[Install](docs/install/)                                                    --
[Docs](docs/)                                                               --
[News](news/)                                                               --
[Lists](lists/)                                                             --
[Chat](https://webchat.freenode.net/?channels=libreboot)                    --
[Bugs](https://notabug.org/libreboot/libreboot/issues)                      --
[Send patches](git.md)                                                      --
[Buy](suppliers.md)

Libreboot is a [free](https://www.gnu.org/philosophy/free-sw.html) (as in
freedom) BIOS or UEFI replacement, initialising the hardware and booting your
operating system. It is also available preinstalled from
[these suppliers](suppliers.md).

We provide user support via [\#libreboot
IRC](https://webchat.freenode.net/?channels=libreboot) on Freenode. Development
discussion also occurs on IRC, and on our [mailing list](lists/). Instructions
for sending patches are [here](git.md).

Why use Libreboot?
------------------

Many people use non-free proprietary boot firmware, even if they use GNU+Linux.
Non-free BIOS/UEFI firmware often
[contains](faq.md#intel) [backdoors](faq.md#amd), can be slow and have severe
bugs, and you are left helpless at the mercy of the developers. By contrast,
libreboot is fully free software, where anyone can contribute or inspect its
code.

Libreboot is faster, more secure and more reliable than most non-free
firmware, and can provide many advanced feature, like encrypted
/boot/, GPG signature checking before booting your kernel, ability to
load an OS *from the flash chip*, and more.

Libreboot's main upstream provider is [coreboot](https://www.coreboot.org/),
which we deblob. We upstream our custom patches to projects like coreboot,
depthcharge, GRUB, and flashrom where possible. Together, we provide an
automated build and installation system with nontechnical documentation,
allowing Libreboot to be widely used.


code:
#!/usr/bin/env bash
#
# Copyright (C) 2017 Alyssa Rosenzweig <alyssa@rosenzweig.io>
# Copyright (C) 2017 Michael Reed <michael@michaelreed.io>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

BLOGTITLE="Libreboot News"
BLOGBASE="https://libreboot.org/"
BLOGDESCRIPTION="News on Libreboot development"

# MANIFEST determines the order of news articles in news/index.md
FILES=$(< news/MANIFEST)

# usage: title file
title() {
    sed -n 1p "$1" | sed -e s-^..--
}

# usage: meta file
meta() {
    file=$1
    URL=$(printf '%s\n' "${file%.md}.html" | sed -e s-news/--)

    printf '%s\n' "[$(title "$file")]($URL){.title}"
    printf '%s\n' "[$(sed -n 3p "$file" | sed -e s-^..--)]{.date}"
    printf '\n'
    tail -n +5 "$file" | perl -p0e 's/(\.|\?|\!)( |\n)(.|\n)*/.../g'

    printf '\n'
    printf '\n'
}

# usage: rss_header
rss_header() {
    printf '%s\n' '<rss version="2.0">'
    printf '%s\n' '<channel>'

    printf '%s\n' "<title>$BLOGTITLE</title>"
    printf '%s\n' "<link>${BLOGBASE}news/</link>"
    printf '%s\n' "<description>$BLOGDESCRIPTION</description>"
}

# usage: rss_main file
rss_main() {
    file=$1

    # render content and escape
    desc=$(sed -e 's/</\</g' "${file%.md}.bare.html" | sed -e 's/>/\>/g')
    url="${file%.md}.html"

    printf '%s\n' '<item>'
    printf '%s\n' "<title>$(title "$file")</title>"
    printf '%s\n' "<link>$BLOGBASE$url</link>"
    printf '%s\n' "<description>$desc</description>"
    printf '%s\n' '</item>'
}

# usage: rss_footer
rss_footer() {
    printf '%s\n' '</channel>'
    printf '%s\n' '</rss>'
}

# generate the index file
cat news-list.md > news/index.md
for f in $FILES
do
    meta "$f" >> news/index.md
done

# generate the RSS index
rss_header > news/feed.xml
for f in $FILES
do
    rss_main "$f" >> news/feed.xml
done
rss_footer >> news/feed.xml

cp news/feed.xml feed.xml


code:
---
title: General management guidelines
x-toc-enable: true
...

This document defines the nature of Libreboot's leadership structure.

Democratic governance of the Libreboot project
----------------------------------------------

In principle and in practise, Libreboot is a collectively and democratically
governed project. Any member of the public can propose anything. Our leadership
is a flat hierarchy; we have no leader!

Our core management team is open to the public; anyone can join it, if they
make substantial contributions to the project and if the current core
management team agrees. Libreboot is a *community* project.

All proposals, big or small, should be discussed and (if approved by core
management) implemented.

Information about code review can be found [on the Git section of the
website](git.md#general-code-review-guidelines).

List of members in the core management team
-------------------------------------------

In alphabetical order:

- Alyssa Rosenzweig is sysadmin and Public Relations manager.
  IRC nick **alyssa**.
- Andrew Robbins is a core developer. IRC nick **and\_who**
- Paul Kocialkowski is a core developer. IRC nick **paulk-X**
  (**X** is variable, and changes over time)
- Leah Rowe is a core developer (and project founder). IRC nick
  **\_4of7**
- Swift Geek is a core developer. IRC nick **swiftgeek**

Generally, the people on this list have these responsibilities:

- Code review (they have merge rights on the Git repositories)
- Voting rights on all major decisions, with community input.
- System administration (where necessary) for Libreboot's infrastructure.
- Moderation of the IRC channel, mailing lists and other discussion mediums.
- Comply with the [Guidelines for Good Conduct](conduct.md)

All members are granted SSH access, with varying levels of access depending on
need. At the very least, all members are able to update the website when new
changes to it are merged in the Git repository.

People of interest
------------------

These people are not part of core management, but still have influence.

Other IRC channel moderators:

- IRC nick **specing** on the Libreboot IRC channel.
- IRC nick **pizzaiolo** on the Libreboot IRC channel.
- IRC nick **jxself** on the Libreboot IRC channel.

Additionally, Libreboot has a separate set of operators on the subreddit
r/libreboot. Check Reddit for more information. Actions taken by moderators
there are also subject to these management guidelines.


code:
% News announcements from the Libreboot project

Updates to libreboot, both technical and organisational, will be written about
here over time. Subscribe to [RSS](/feed.xml) for notifications.

-------------------------------------------------------------------------------


code:
news/new-mailing-lists.md
news/andrew-robbins-new-maintainer.md
news/formalised-structure.md
news/proposal-rejoin-gnu.md
news/unity.md

path: www/news/MANIFEST


code:
% Welcoming Andrew Robbins
% Leah Rowe and Alyssa Rosenzweig
% 4 Jun 2017

On 25 April, Libreboot adopted new [collective governance
policies](../management.md), creating a flat-hierarchy leadership of four
people. As a result, all patches are reviewed, and all major decisions are
voted on by the maintainers with community input. These policies formalise our
democratic standards.

Today, we welcome Andrew Robbins (IRC nick `and_who` and
[NotABug](https://notabug.org) user [kragle](https://notabug.org/kragle)) as
our first new maintainer under the new policy. Going forward, Andrew will gain
push access to Libreboot in order to review patches, as well as voting rights
and IRC operator status.

Andrew works on critical improvements to the build system, many of which have
already been merged. He is passionate about Libreboot, understanding the
project at a deep level, and he has been an active member of the community.
Thus, with unanimous agreement from the existing maintainers, Andrew has joined
the project officially.

We look forward to Andrew's next contributions as our project continues to
grow.

The new list of maintainers is as follows:

- Alyssa Rosenzweig
- Andrew Robbins
- Leah Rowe
- Paul Kocialkowski
- Swift Geek


code:
% Formalising Democracy
% Alyssa Rosenzweig
% 25 Apr 2017

One month ago, the [Open Letter to the Free Software Community](/news/unity.md)
was published, alluding to the new Libreboot leadership. Today, the ideals
expressed there have been formalised into an official project policy. In the
new [General Management Guidelines](/management.md), the ins-and-outs of our
democratic system is codified, including the formal team list. Hint, hint: the
structure isn't "I, Alyssa Rosenzweig, decide everything and Thou shall bow
down to me"! There are four core team members, and we welcome community
feedback for major decisions.

There was an underlying tension in the letter: should Libreboot rejoin GNU? On
purely political and technical levels, the answer is a resounding "yes". We
share the mission of spreading free software. Our communities overlap. Most of
the Libreboot community uses GNU software, and much of GNU uses libreboot.
Technically, the tighter integration is useful. Politically, closer ties will
strengthen both of our projects. But this is neither completely a political or
technical question -- it is a human one.

There is no easy answer to this. But the best course of action is to reach out
beyond the team to the community at large. A number of people ranging from
Libreboot users to GNU developers to casual bystanders chimed in, and the
answer was an overwhelming "yes, you should have done this a month ago!"

With that in mind, we have reapplied for GNU. Leah conducted the initial
discussions, such as the Reddit thread, as she felt that she needed to correct
her own error. I have since been handling the application itself, which was
submitted recently. GNU has not yet made a decision on the matter. Ultimately,
it will be up to Richard Stallman himself whether the mutual benefits of
joining will outweigh any potential awkwardness.

No matter the response, Libreboot remains committed to free software. Whether
or not we need a g'new name, this will never change.


code:
% New development mailing list for Libreboot
% Leah Rowe
% 10 Jun 2017

Our sysadmin, Alyssa Rosenzweig, has set up a mailing list on libreboot.org
infrastructure, for development discussions.

The mailing list address is
[development@libreboot.org](mailto:development@libreboot.org)

Information about the mailing list and how to subscribe are
[here](../lists/). Archives of discussion threads
are [here](../pipermail/development/).

This replaces the mailing lists that we had before. The mailing list software
in use is [GNU Mailman](https://www.gnu.org/software/mailman/), which is also
used by many other free software projects and is very popular. If you already
use mailing lists in other projects, then the way to use Libreboot's new
mailing list is exactly the same.

This mailing list is for development discussion *only*. User support is still
handled via #libreboot on Freenode IRC, as always.

This new mailing list will also be used for beta testing of upcoming stable
releases, from now on. Work is currently underway on a new Libreboot release.


code:
% Community feedback needed on whether Libreboot should re-join the GNU project
%
% 22 Apr 2017

Community feedback is needed on whether Libreboot should re-join the GNU
project, having previously been a member. The discussion place for this topic
is on [this thread in the Libreboot subreddit at reddit.com/r/libreboot/](https://www.reddit.com/r/libreboot/comments/66tdds/proposal_for_libreboot_rejoin_gnu_community/). With sufficient community support, Libreboot will
apply to re-join to become a member of the GNU project. Full reasoning and
history behind this proposal is detailed in the thread.


code:
% Open Letter to the Free Software Community
%
% 2 Apr 2017

To the free software community:

Over the past six months, the Libreboot project has been in a state of discord.
After an issue with a transgender employee at the FSF escalated, Libreboot
publicly left GNU with little consultation from the community. Relations with
so many people were strained. Friendships broken, lines of code never written:
the chaos needs to come to an end.

A series of organisational issues with Libreboot enabled this fallout to occur.
We have since corrected them:

Previously, the libreboot repository and the website could only be modified by
the project leader, Leah Rowe. This setup created a single point of failure,
with little leeway for dissenting contributors. Since then, I have joined the
project as the sysadmin. Along with another contributor, Sebastian "Swift Geek"
Grzywna, direct access to the code and servers is shared. Though the project
cannot yet be completely decentralised, this change is a win for transparency.

Previously, most of libreboot.org, including public statements such as those
regarding GNU, were issued by Leah herself. The rest of the team and the
community were not consulted. As Damien Zammit, a former contributor noted, the
word "we" on old Libreboot notices meant "Leah". But alas, there is no room for
the "royal we" in democracy.

Finally, on a personal note, Leah was at the time struggling with gender
dysphoria and substance abuse. Since then, she has been managing these issues.
She agrees that her behaviour was rash and is determined to find a unifying
solution.

With all of this in mind, were the allegations against the Free Software
Foundation true? Perhaps. Perhaps not. At this point, it doesn't matter.
Indeed, it is unlikely that Libreboot will ever rejoin GNU, but feuding in an
already fragmented community helps nobody. The world of free software is
shrinking and under attack. Though the FSF may make mistakes from time to time,
so do we. We do not need another divide.

Similarly, we would like to work closely with librecore, another project
working to deblob coreboot, whose team includes Damien Zammit. Once librecore
matures, libreboot plans to switch to librecore in lieu of our current
deblobbed fork. That is, there will be less duplication of effort; instead of
competing with librecore, libreboot will complement it.

As a technical update, we are currently working on a Libreboot port to
the X220. Leah and Swift are investigating ways to disable the ME on
Sandybridge hardware, which potentially means more modern Intel hardware may be
supported. Additionally, Paul Kocialkowski has been working on supporting
several new Chromebooks with ARM chips; these ports will also be available in
an upcoming release.

No more "royal we". No more notorious surprises. No more late night
"typofixes".

Transparency and collaboration are the way forward.

~Alyssa Rosenzweig

### A message from Leah, to further complement Alyssa's submission:

I acknowledge that what I did was wrong. Although I felt justified at the time,
I ended up hurting a lot of people, most of whom were uninvolved with any of
the relevant events. At the time of taking Libreboot out of GNU, I was going
through intense personal difficulty in my life, and I was highly unstable.
Presented with a similiar situation, I likely won't respond the way I did
before. I've changed a lot, and I promise this type of thing won't happen
again.

What I'd like the most, is to simply focus on Libreboot as I've always done,
and to forget about what happened in the past and move on.

I sincerely hope that the FSF, GNU project and others who I have hurt, can do
the same. My only goal at present is to continue improving Libreboot, and to do
everything in my power to make libre hardware a reality for everyone, as is the
goal of the Libreboot project.

I will remain in my place as a developer in this project, but everything that I
do from now on will be the result of open collaboration with others in the
project. I very nearly single handedly destroyed this project, and caused a lot
of damage to the entire community, damage which I now wish to repair. I love
Libreboot, Free Software and the community, and my only wish is to see it
thrive.

I wish well any and all outreach organisations that do work with the FSF; e.g.
Outreachy, who are working to do what they can to improve conditions for women,
LGBT people and other minorities in the sphere of computing and engineering
fields, related to Free Software.

I hope that any damage I caused to the community is not permanent.

I'm deeply sorry for the damage and upset that I caused. I will not repeat the
same mistakes twice. To a very specific person, who cannot be named in the
interest of their privacy, but for whom context will allow that person
to know this is for them: I'm especially sorry for the damage that I did to
you during those months, and I sincerely hope that you get what you are
currently seeking. I fully support you in your endeavour, and if I could help
you, I would. You still mean a great deal to me.

I'm especially sorry to John Sullivan and Ruben Rodriguez of the FSF, both of
whom I publicly slandered on the Libreboot website. They did not deserve any of
that. I was being highly abusive towards you both.

I would also like to express my sincerest apology to those GNU maintainers
whose emails I published on the Libreboot website, when all of that chaos was
underway.

I'm sorry to all the other Libreboot maintainers at the time, some of whom felt
like they had no choice but to quit the project because of my actions. Doubly
so for Damien Zammit and Timothy Pearson, both of whom I let down in various
ways afterwards aswell.

I would like to sincerely apologize to Timothy Pearson of Raptor Engineering
in particular, for the damage that I caused with Libreboot's exit from GNU,
while you were running your TALOS workstation campaign. Although I do not know
whether the campaign would have succeeded without all that chaos, my own
actions certainly did not help.

Finally, I would like to once again apologize to the community as a whole, for
the damage that I caused. I hope that I can prove to you all that I do wish to
make amends for the damage, and to improve, and to re-build bridges with the
community, and to once again work with the community in bringing Libreboot and
Free Software forward, into the future.

~Leah Rowe


code:
#!/usr/bin/env bash
#
# Copyright (C) 2017 Alyssa Rosenzweig <alyssa@rosenzweig.io>
# Copyright (C) 2017 Leah Rowe <info@minifree.org>
# Copyright (C) 2017 Michael Reed <michael@michaelreed.io>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

[ "x${DEBUG+set}" = 'xset' ] && set -v
set -e

FILE=${1%.md}
TMPFILE=$(mktemp -t libreboot_www.XXXXXXXXXX)

cat "$1" > "$TMPFILE"

OPTS="-T Libreboot"

if [[ $FILE == "index" || $FILE == "./index" ]]; then
        OPTS="--css /headercenter.css"
else
        if [[ $FILE == *suppliers ]]
        then
            RETURN=""
        else
            if [[ $FILE == *index ]]
            then
                DEST="../"
            else
                DEST="./"
            fi

            RETURN="Edit this page -- Back to previous index"
            OPTS="-T Libreboot"
        fi
fi

if [[ $FILE = *suppliers ]]; then
        printf '\n%s\n' "Edit this page -- Back to previous page" >> "$TMPFILE"
fi

if [[ $FILE != "./docs/fdl-1.3" && $FILE != "docs/fdl-1.3" &&
      $FILE != "./conduct"      && $FILE != "conduct" ]]; then
    cat footer.md >> "$TMPFILE"
fi

# change out .md -> .html
sed -i -e 's/\.md\(#[a-z\-]*\)*)/.html\1)/g' "$TMPFILE"
sed -i -e 's/\.md\(#[a-z\-]*\)*]/.html\1]/g' "$TMPFILE"

# change out .md -> .html
sed -i -e 's/\.md\(#[a-z\-]*\)*)/.html\1)/g' "$TMPFILE"
sed -i -e 's/\.md\(#[a-z\-]*\)*]/.html\1]/g' "$TMPFILE"

# work around issue #2872
TOC=$(grep -q "^x-toc-enable: true$" "$TMPFILE" && printf '%s\n' "--toc --toc-depth=2") || TOC=""

# work around heterogenous pandoc versions
SMART=$(pandoc -v | grep -q '2\.0' || printf '%s\n' "--smart") || SMART=""

# chuck through pandoc
#
# $OPTS must not be quoted, otherwise pandoc interprets '--css /headercenter.css'
# as one argument, when it is actually two.
pandoc $TOC $SMART "$TMPFILE" -s --css /global.css $OPTS \
        --template template.html --metadata return="$RETURN" > "$FILE.html"

# generate section title anchors as [link]
sed -i -e 's_^<h\([123]\) id="\(.*\)">\(.*\)</h\1>_
<h\1 id="\2">\3</h\1>[link]
_' "$FILE.html"

# clean up temporary file
rm -f "$TMPFILE"


code:
---
title: Suppliers selling or providing Libreboot pre-installed
...

Libiquity
---------

Patrick McDermott, Libiquity's founder, is a former Libreboot
developer. **Ships to USA only**

-   [Taurinus X200 laptop](https://shop.libiquity.com/product/taurinus-x200) (FSF RYF certified)
-   [Libreboot chassis](https://shop.libiquity.com/product/libreboot-stickers-shaped-matte-vinyl-2x2.25-3-pack) and [Libreboot Inside stickers](https://shop.libiquity.com/product/libreboot-inside-case-badges-3-pack)

Ministry of Freedom (Minifree)
------------------------------

Leah Rowe, Minifree's founder, is also Libreboot's founder and is an active
Libreboot developer. Minifree is the first company to achieve FSF RYF
endorsement on a computer system, and invests money directly into Libreboot.

**Minifree ships worldwide, to all countries.**

Laptops:

-   [Libreboot T400 laptop](https://minifree.org/product/libreboot-t400/) (FSF RYF certified)

Desktops:

-   [Libreboot D16 desktop/workstation](https://minifree.org/product/libreboot-d16/)

Servers:

-   [Libreboot D16 server](https://minifree.org/product/libreboot-d16-server/)

Services:

-   [Libreboot installation service](https://minifree.org/product/libreboot-installation-service/)

Merchendise:

-   [Libreboot T400 battery](https://minifree.org/product/libreboot-t400-battery/)
-   [Libreboot X200 battery](https://minifree.org/product/libreboot-x200-battery/)
-   [Libreboot X200 docking station](https://minifree.org/product/docking-station-for-libreboot-x200/)
-   [Libreboot stickers](https://minifree.org/product/libreboot-stickers/)

Technoethical
-------------

Technoethical (formerly Tehnoetic) is a team of free software activists and
developers that are selling hardware pre-installed with libreboot as a way to
fund the activity within their nonprofit foundation.

**Ships worldwide, to all countries.**

Services:

-   [Libreboot installation service](https://tehnoetic.com/tet-lis)

Laptops:

-   [Technoethical T500 laptop](https://tehnoetic.com/tet-t500)
-   [Technoethical T400 laptop](https://tehnoetic.com/tet-t400)
-   [Technoethical T400S laptop](https://tehnoetic.com/tet-t400s)
-   [Technoethical X200 Tablet laptop](https://tehnoetic.com/tet-x200t)
-   [Technoethical X200 laptop](https://tehnoetic.com/tet-x200)

Vikings
-------

Vikings is the first company to offer hosting on hardware pre-installed with
libreboot and they are also selling the hardware itself to fund the building
of their libreboot-powered datacenter.

**Ships worldwide, to all countries.**

Servers:

-   [Vikings D16 1U server](https://store.vikings.net/libre-friendly-hardware/the-server-1u)

Mainboards:

-   [Vikings D16 mainboard](https://store.vikings.net/libre-friendly-hardware/d16-ryf-certfied) (FSF RYF certified)

Desktops:

-   [Vikings D16 workstation](https://store.vikings.net/libre-friendly-hardware/vikings-d16-workstation)

Laptops:

-   [Vikings X200 laptop](https://store.vikings.net/libre-friendly-hardware/x200-ryf-certfied) (FSF RYF certified)

Other suppliers
===============

Sellers on eBay
---------------

On the eBay website, in various countries, you can search for libreboot and
you may find some individual sellers providing Libreboot-preinstalled hardware.

We cannot verify the quality of these suppliers, but they do exist.

Some of them also provide choice of GNU+Linux distribution, or they may provide
services where you can ship your Libreboot-compatible device to them and they
would install Libreboot for you.

This can be useful for some people, but due to the nature of eBay, we cannot
link to them since eBay listings are regularly deleted due to expiration (some
sellers may choose to have longer listings, or renew expired listings).

There may also be other websites similar to eBay (e.g. mercado livre, available
for several South American countries) that might have Libreboot hardware on
them.

**If you are considering purchasing from a supplier on eBay, make sure to read
their feedback comments for other products that they sell, and check their
seller rating. Don't get duped by a bad seller!**

Workshops/hackerspaces
----------------------

You may have a GNU+Linux User Group, free software workshop or hackerspace near
you that can help you with installing Libreboot, for instance.


code:
<!DOCTYPE html>

  <meta charset="utf-8">
  <meta name="generator" content="pandoc">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
$for(author-meta)$
  <meta name="author" content="$author-meta$">
$endfor$
$if(date-meta)$
  <meta name="dcterms.date" content="$date-meta$">
$endif$
$if(keywords)$
  <meta name="keywords" content="$for(keywords)$$keywords$$sep$, $endfor$">
$endif$
  <title>$if(title-prefix)$$title-prefix$ – $endif$$pagetitle$</title>

$if(quotes)$

$endif$
$if(highlighting-css)$

$endif$
$for(css)$
  <link rel="stylesheet" href="$css$">
$endfor$
$if(math)$
  $math$
$endif$
$for(header-includes)$
  $header-includes$
$endfor$
<link rel="alternate" type="application/rss+xml" title="RSS Feed" href="/feed.xml"/>

$for(include-before)$
$include-before$
$endfor$
$if(title)$

$title$

$if(subtitle)$

$subtitle$

$endif$
$for(author)$

$author$

$endfor$
$if(date)$

$date$

$endif$

$endif$
$if(return)$
$return$
$endif$
$if(toc)$

$toc$

$endif$
$body$
$for(include-after)$
$include-after$
$endfor$


code:
# ---> Ada
# Object file
*.o

# Ada Library Information
*.ali

# ---> Anjuta
# Local configuration folder and symbol database
/.anjuta/
/.anjuta_sym_db.db

# ---> AppEngine
# Google App Engine generated folder
appengine-generated/

repo_name: kqxsmt/xsmthomnay

path: .gitignore


code:
# xsmthomnay

Dự đoán xổ số miền trung chính xác nhất ngày 26.6.2019


code:
[*]
indent_style = space
indent_size = 2
end_of_line = lf

[*.py]
indent_style = space
indent_size = 4

[xonshrc]
indent_style = space
indent_size = 4

[sxhkdrc]
indent_style = space
indent_size = 2

[bspwmrc]
indent_style = space
indent_size = 2

path: .editorconfig

license: unknown


code:
*.#*
*.cache
*.directory
*.eld
*.log
.cache/
.edbi-ds-history
.org-id-locations
.python-environments/
__pycache__/
auto-save-list
backup
backups/
bookmarks
cache/
config.el
docsets/
el-get
el-get/
straight
straight/
elpa
eshell/
history
info/
init.el
org-caldav*.*
private.org
quelpa/
recentf
recentf\~
session.*
syntax: glob
tagged
tmp
tramp
vimish-fold/
watch_later/


code:
* Personal dotfiles
Pantheon Dotfiles


code:
* TODO Manage dotfiles:
  Manage dotfiles with external tools:
  - [ ] Tools
    - [ ] [[https://www.gnu.org/software/stow/][GNU Stow]]
    - [ ] [[http://www.pyinvoke.org/][Invoke]]


code:
#!/usr/bin/env python
# Import hashlib library (md5 method is part of it)
import hashlib
import sys

# File to check
file_name = sys.argv[1]

# Correct original md5 goes here
sums = sys.argv[2]

# Open,close, read file and calculate MD5 on its contents
with open(file_name, 'rb') as file_to_check:
    # read contents of the file
    data = file_to_check.read()
    # pipe contents of the file through
    md5_returned = hashlib.md5(data).hexdigest()

# Finally compare original MD5 with freshly calculated
if sums == md5_returned:
    print("MD5 verified.")
else:
    print("MD5 verification failed!.")


code:
#!/usr/bin/sh

killall -q clipster

while pgrep -x clipster >/dev/null; do sleep 1; done

clipster -d &


code:
#!/bin/bash

IGNORE_FILES=".*\.\(org\|pdf\|tex\|png\|PNG\|otf\)"
IGNORE_FOLDERS="build|img|tex|font"

dir=${PWD}
builddir="$dir/build"

[ -d "$builddir" ] || rm -rf "$builddir"

mkdir -p $builddir

xelatex_opts+=" -synctex=1"
xelatex_opts+=" -interaction=nonstopmode"
xelatex_opts+=" -shell-escape"

echo -e "\n------------------ xelatex --------------------\n"

for i in {1..2}
do
  xelatex $xelatex_opts $1
  # if [ "$i" -eq "2" ]; then
  #   find $dir \( ! -regex '.*/\..*' \) -type f ! -regex $IGNORE_FILES -exec mv -t $builddir {} +
  #   find $dir -maxdepth 1 \( ! -regex '.*/\..*' \) -type d -not -path $dir | egrep -v $IGNORE_FOLDERS | xargs mv -t $builddir
  # fi
done


code:
#!/bin/sh

USERID=`id -u`
if [[ ! -e /tmp/emacs$USERID/server ]]
then
  emacs --daemon
  emacsclient -c -n -e '(switch-to-buffer "*dashboard*")'
else
  emacsclient -c -n -e '(switch-to-buffer "*dashboard*")'
fi


code:
#!/bin/bash

# test args
if [ ! ${#} -ge 2 ]; then
    echo 1>&2 "Usage: ${0} LOCAL REMOTE [MERGED BASE]"
    echo 1>&2 "       (LOCAL, REMOTE, MERGED, BASE can be provided by \`git mergetool'.)"
    exit 1
fi

# tools
_EMACSCLIENT=/usr/bin/emacsclient
_BASENAME=/bin/basename
_CP=/bin/cp
_EGREP=/bin/egrep
_MKTEMP=/bin/mktemp

# args
_LOCAL=${1}
_REMOTE=${2}
if [ ${3} ] ; then
    _MERGED=${3}
else
    _MERGED=${_REMOTE}
fi
if [ ${4} -a -r ${4} ] ; then
    _BASE=${4}
    _EDIFF=ediff-merge-files-with-ancestor
    _EVAL="${_EDIFF} \"${_LOCAL}\" \"${_REMOTE}\" \"${_BASE}\" nil \"${_MERGED}\""
elif [ ${_REMOTE} = ${_MERGED} ] ; then
    _EDIFF=ediff
    _EVAL="${_EDIFF} \"${_LOCAL}\" \"${_REMOTE}\""
else
    _EDIFF=ediff-merge-files
    _EVAL="${_EDIFF} \"${_LOCAL}\" \"${_REMOTE}\" nil \"${_MERGED}\""
fi

# console vs. X
#if [ "${TERM}" = "linux" ]; then
#    unset DISPLAY
#    _EMACSCLIENTOPTS="-t"
#else
#    _EMACSCLIENTOPTS="-c"
#fi

_EMACSCLIENTOPTS="-t"

# run emacsclient
${_EMACSCLIENT} ${_EMACSCLIENTOPTS} -a "" -e "(${_EVAL})" 2>&1

# check modified file
if [ ! $(egrep -c '^(<<<<<<<|=======|>>>>>>>|####### Ancestor)' ${_MERGED}) = 0 ]; then
    _MERGEDSAVE=$(${_MKTEMP} --tmpdir `${_BASENAME} ${_MERGED}`.XXXXXXXXXX)
    ${_CP} ${_MERGED} ${_MERGEDSAVE}
    echo 1>&2 "Oops! Conflict markers detected in $_MERGED."
    echo 1>&2 "Saved your changes to ${_MERGEDSAVE}"
    echo 1>&2 "Exiting with code 1."
    exit 1
fi

exit 0


code:
#! /bin/sh

MON_ID=$(bspc query -M -m "$1")
MON_POS="$2"

[ $(bspc query -M -m "$MON_POS") != "$MON_ID" ] && bspc monitor "$MON_POS" -s "$MON_ID"

bspc subscribe monitor_swap | while read msg ; do
	[ $(bspc query -M -m "$MON_POS") != "$MON_ID" ] && bspc monitor "$MON_POS" -s "$MON_ID"
done


code:
#!/bin/sh
OPTIONS="Reboot system\nPower-off system\nSuspend system\nLock system\nLogout session"
LAUNCHER="rofi -width 10 -dmenu -i -p rofi-power"

# Show exit wm option if exit command is provided as an argument
if [ ${#1} -gt 0 ]; then
	OPTIONS="Exit window manager\n$OPTIONS"
fi

option=$(echo -e $OPTIONS | $LAUNCHER | awk '{print $1}' | tr -d '\r\n')
echo $option
if [ ${#option} -gt 0 ]; then
	case $option in
    Exit)
      eval $1
      ;;
	  Lock)
		  loginctl lock-session
		  ;;
	  Logout)
		  session=$(loginctl session-status | awk 'NR==1{print $1}')
		  loginctl terminate-session $session
		  ;;
	  Suspend)
		  systemctl suspend
		  ;;
	  Reboot)
		  systemctl reboot
		  ;;
	  Power-off)
		  systemctl poweroff
		  ;;
    *)
      ;;
	esac
fi
exit 0


code:
#!/bin/bash

# Script intended to be executed from ncmpcpp (execute_on_song_change
# preference) running from urxvt to set album cover as background image

MPD_CONF=~/.config/mpd/mpd.conf
MUSIC_DIR=$( cat "$MPD_CONF" | grep -v '#' | grep 'music_directory' | cut -d ' ' -f2 | awk '{print $2}' | sed 's/"//g' )
DARKEN=70

TMP=/tmp
COVER=/tmp/cover.jpg
IMG_REG=".*/.*\(Front\|front\|Cover\|cover\|Art\|art\|Folder\|folder\).*[.]\(jpe?g\|png\|gif\|bmp\)"

function reset_background
{
  # is there any better way?
  printf "\e]20;;100x100+1000+1000\a"
}

{
  album="$(mpc --format %album% current)"
  artist="$(mpc --format %artist% current)"
  file="$(mpc --format %file% current)"
  dir="$MUSIC_DIR/$artist/$album"
  if [[ -d "$dir" ]] ; then
    album_dir="$dir"
  else
    album_dir="$MUSIC_DIR/${file%/*}"
  fi

  [[ -z "$album_dir" ]] && exit 1

  covers="$(find "$album_dir/" -type d -exec find {} -maxdepth 1 -type f -regex "$IMG_REG" \; )"
  src="$(echo -n "$covers" | head -n1)"
  darkenimg="$TMP/darken.jpg"
  rm -f "$COVER" "$darkenimg"
  if [[ -n "$src" ]] ; then
    light="$((100 - $DARKEN))"
    convert "$src" -fill "gray${light}" +level ${light}%,${light}% \
            +matte "$darkenimg"
    composite "$darkenimg" -compose Multiply "$src" "$COVER"
    if [[ -f "$COVER" ]] ; then
      printf "\e]20;${COVER};100x100+50+50:op=keep-aspect\a"
    else
      reset_background
    fi
  else
    reset_background
  fi
} &


code:
#!/bin/sh

# Terminate already running bar instances
killall -q polybar

# Wait until the processes have been shut down
while pgrep -x polybar >/dev/null; do sleep 1; done

# Launch bar1 and bar2
DISPLAY1="$(polybar -m | awk -F: '{print $1}' | grep 'eDP1\|VGA-0')"
[[ ! -z "$DISPLAY1" ]] && xrandr --output $DISPLAY1 --auto --primary & MONITOR=$DISPLAY1 polybar top &

DISPLAY2="$(polybar -m | awk -F: '{print $1}' | grep 'HDMI1\|HDMI-2')"
[[ ! -z "$DISPLAY2" ]] && xrandr --output $DISPLAY2 --left-of $DISPLAY1 &
echo "Bars launched..."


code:
#!/usr/bin/env sh

export SYSTEMD_COLORS=0
term=${ROFI_SYSTEMD_TERM-urxvtcd --geometry 100x20 -e}
default_action=${ROFI_SYSTEMD_DEFAULT_ACTION-"list_actions"}

function user_units {
	SYSTEMD_COLORS=0 systemctl --user list-unit-files | tail -n +2 | head -n -2 |
		awk '{print $0 "  user"}'
}

function system_units {
	systemctl list-unit-files | tail -n +2 | head -n -2 |
		awk '{print $0 "  system"}'
}

enable="Alt+e"
disable="Alt+d"
stop="Alt+k"
restart="Alt+r"
tail="Alt+t"
list_actions="Alt+l"

all_actions="enable
disable
stop
restart
tail
list_actions"

function select_service_and_act {
	result=$(rofi -dmenu -i -p "systemd unit" \
	              -kb-custom-1 "${enable}" \
	              -kb-custom-2 "${disable}" \
	              -kb-custom-3 "${stop}" \
	              -kb-custom-4 "${restart}" \
	              -kb-custom-5 "${tail}" \
	              -kb-custom-6 "${list_actions}")

	rofi_exit="$?"

	case "$rofi_exit" in
		1)
			action="exit"
			exit 1
			;;
		10)
			action="enable"
			;;
		11)
			action="disable"
			;;
		12)
			action="stop"
			;;
		13)
			action="restart"
			;;
		14)
			action="tail"
			;;
		15)
			action="list_actions"
			;;
		*)
			action="$default_action"
			;;
	esac

	selection="$(echo $result | sed -n 's/ \+/ /gp')"
	service_name="$(echo $selection | awk '{ print $1 }' | tr -d ' ')"
	is_user="$(echo $selection | awk '{ print $3 }' )"

	case "$is_user" in
		user*)
			user_arg="--user"
			command="systemctl $user_arg"
			;;
		system*)
			user_arg=""
			command="sudo systemctl"
			;;
		*)
			command="systemctl"
	esac

	to_run="$(get_command_with_args)"
	echo "Running $to_run"
	eval "$to_run"
}

function get_command_with_args {
	case "$action" in
		"tail")
			echo "$term 'journalctl $user_arg -u $service_name -f'"
      action=$($term journalctl $user_arg -u $service_name -f)
			;;
		"list_actions")
			action=$(echo "$all_actions" | rofi -dmenu -i -p "Select action: ")
			get_command_with_args
			;;
		*)
			echo "$command $action $service_name"
			;;
	esac
}

{ user_units; system_units; } | column -tc 1 | select_service_and_act


code:
#!/usr/bin/env zsh
#
# Setup outputs with xrandr as a backend and dmenu as a frontend
# https://hoodoo.github.io/#sec-6-2-2
# external commands: cat, cut, dmenu, grep, sed, xrandr
# Released under GPLv2

typeset XRANDR_TXT # readonly; stdout of running xrandr without any options
typeset -A OUTPUT_CONFIGURED # key=connected output name

function main() {
  local -i iteration
  local max_iteration
  local output
  local mode
  local position
  local xrandr_cmd

  environment_check

  max_iteration=${(w)#OUTPUT_CONFIGURED}
  xrandr_cmd='xrandr'
  while ! all_outputs_configured && (( $iteration <= $max_iteration )); do
    if (( iteration++ )); then
      select_output 'Select next output:' 'unconfigured' | read output
      select_position "${output}" | read position
      [[ "${position}" != '--off' ]] && select_mode "${output}" | read mode
      OUTPUT_CONFIGURED[${output}]='true'
    else
      select_output 'Select primary output:' 'all' | read output
      select_mode "${output}" | read mode
      OUTPUT_CONFIGURED[${output}]='true'
      position='--primary'
    fi
    xrandr_cmd+=" --output ${output} ${position} ${mode}"
  done

  ${=xrandr_cmd}
}

################################################################################
# Uses dmenu to select an output. Skips menu if only 1 option is available.
# Prints the name of the selected output to stdout
# Global variables:
#  OUTPUT_CONFIGURED
# Arguments:
#  $1=prompt
#  $2=group of outputs. valid options are configured, unconfigured, all
# Returns:
#  257=bad arguments
#  258=bad selection (TODO)
#  259=no options available
################################################################################
function select_output() {
  local -a menu
  local output
  local -ir err_bad_args=257
  local -ir err_bad_selection=258
  local -ir err_no_options=259

  case "$2" in
    'configured')
      for output in ${(k)OUTPUT_CONFIGURED}; do
        ${OUTPUT_CONFIGURED[$output]} && menu+=("$output")
      done
      ;;
    'unconfigured')
      for output in ${(k)OUTPUT_CONFIGURED}; do
        ${OUTPUT_CONFIGURED[$output]} || menu+=("$output")
      done
      ;;
    'all') menu=(${(k)OUTPUT_CONFIGURED}) ;;
    *) return "${err_bad_args}" ;;
  esac

  case ${#menu} in
    0) return "${err_no_options}" ;;
    1) echo "${menu}" ;;
    *) echo ${(F)menu} | rofi -dmenu -l 10 -p "$1" ;;
  esac
}

################################################################################
# Uses dmenu to select the position of a given output relative to an already
# configured output. --same-as and --off are considered a position.
# Prints in the form of xrandr option (eg, '--right-of DP1') to stdout
# Global variables:
#  OUTPUT_CONFIGURED
# Arguments:
#  $1=name of output to configure
# Returns:
#  257=bad argument (TODO: check validity beyond existance)
#  258=bad selection
#  259=no configured outputs to relate to (ie, no anchor)
################################################################################
function select_position() {
  local anchor
  local selection
  local -ir err_bad_arg=257
  local -ir err_bad_selection=258
  local -ir err_no_anchor=259

  [[ -z $1 ]] && return "${err_bad_arg}"

  select_output "Set $1 relative to:" 'configured' | read anchor
  [[ $? -eq 257 ]] && return "${err_no_anchor}"

  echo "left of ${anchor}
right of ${anchor}
above ${anchor}
below ${anchor}
mirror ${anchor}
off" | rofi -dmenu -l 10 -p "Select position of $1:" | read selection

  case "${selection[(w)1]}" in
    left) echo "--left-of ${anchor}" ;;
    right) echo "--right-of ${anchor}" ;;
    above) echo "--above ${anchor}" ;;
    below) echo "--below ${anchor}" ;;
    mirror) echo "--same-as ${anchor}" ;;
    off) echo "--off" ;;
    *) return "${err_bad_selection}" ;;
  esac
}

################################################################################
# Uses dmenu to display the detected mode options for a given output and lets
# the user select a mode to use. Prints choice in xrandr option format
# (eg, '--mode 800x600' or '--auto') to stdout
# Global variables:
#  XRANDR_TXT
#  CONNECTED_OUTPUT
#  XRANDR_CMD (via primary_set())
# Arguments:
#  $1 - name of which output we are working with
# Returns:
#  257=bad arguements; given output ($1) not found/connected (TODO)
#  258=bad selection
################################################################################
function select_mode() {
  local menu
  local selection
  local -ir err_bad_args=257
  local -ir err_bad_selection=258

  if [[ -z $1 ]] && return "${err_bad_args}"

  # TODO: make this not ugly. A better sed should negate the need for cut/grep
  # Should probably parse (sed) seperately then assign to the array. Or not
  # use an array at all.
  menu="$(echo \"${XRANDR_TXT}\" \
    | sed -n '/^'$1' /,/^[^ ]/ s/ * //p' \
    | cut -d ' ' -f 1 \
    | grep x \
    | cat <(echo auto) -)"

  echo "${menu}" | rofi -dmenu -l 10 -p "Select mode for $1:" | read selection

  case "${selection}" in
    'auto') echo '--auto' ;;
    *x*) echo "--mode ${selection}" ;;
    *) return "${err_bad_selection}" ;;
  esac
}

################################################################################
# Checks to see if all the outputs have been configured
# global variables:
#  OUTPUT_CONFIGURED
# Arguments:
#  none
# Returns:
#  0 - all outputs are configured
#  257 - at least 1 output not configured
################################################################################
function all_outputs_configured() {
  local config

  for config in ${OUTPUT_CONFIGURED}; do
    $config || return 257
  done

  return 0
}

function environment_check() {
  if ! command -v cat &>/dev/null; then
    echo 'You seem to be missing coreutils. You'\''re gonna have a bad time.' >&2
    exit 255
  elif ! command -v grep &>/dev/null; then
    echo 'grep seems to be missing. You'\''re gonna have a bad time.' >&2
    exit 255
  elif ! command -v xrandr &>/dev/null; then
    echo "Try xrandr-dmenu without xrandr, and you're gonna have a bad time." >&2
    exit 255
elif ! command -v rofi &>/dev/null; then
    echo "Try xrandr-dmenu without dmenu, and you're gonna have a bad time." >&2
    exit 255
  elif ! xset q &>/dev/null; then
    echo 'Woah there, cowboy! You need to run this from inside X!' >&2
    exit 1
  fi
}
function initialize_globals() {
  local output

  XRANDR_TXT="$(xrandr)"
  for output in $(grep ' connected' <<< "${XRANDR_TXT}" | cut -d ' ' -f 1); do
    OUTPUT_CONFIGURED[${output}]='false'
  done
}

initialize_globals
readonly XRANDR_TXT
main


code:
#!/bin/env sh
command="rofi -width 15 -run-command \"zsh -i -c '{cmd}'\" -show run"

[[ -d "$HOME/.bin" ]] && PATH=$HOME/.bin:$PATH eval $command || eval $command


code:
#!/bin/sh

# Verify clipster is running, fail otherwise
clipster -o > /dev/null 2>&1
if [ $? -ne 0 ]; then
  echo 'Failed to retrieve history from Clipster, please ensure daemon is running!'
  exit 1
fi

# Extract clipboard history from clipster and format for rofi
#  - Remove Newlines from clips
#  - Limit line length to 200 chars (for display in rofi)
#  - Split into lines based on NUL byte
#  - Remove Leading whitespace
#  - Remove empty clipboard items
#  - Add line numbers to clip items
# NOTE: This is all done in a single line because bash can't store a NUL byte
C_HIST="$(clipster -c -o -n 500 -0 \
        | gawk 'BEGIN {RS = "\0"; ORS = "\0"} NF > 0 { print substr($0, 1, 250) }' \
        | gawk 'BEGIN {RS = "\0"; FS="\n"; OFS=" " } { $1=$1; print $0 }'  \
        | sed 's/^ *//' \
        | gawk '{printf("%003d %s\n", NR, $0)}')"

# Echo clipboard items to Rofi and save the selection made by user
# if [[ -t 0 ]]; then
#   SELECTION="$(echo "$C_HIST" | fzf-tmux -d 15 --prompt='selection: ')"
# else
SELECTION="$(echo "$C_HIST" | rofi -dmenu -i -lines 10 -width 40 -p 'Clipboard selection: ')"
# fi

# Verify user made a selection
if [ -n "$SELECTION" ]; then

  # Retrieve the line number from the beginning of selection and remove leading zeros
  NUMBER="$(echo "$SELECTION" | cut -c1-3 | sed 's/^0*//')"

  # Extract clipboard history from clipster and find the nth non-empty clip based selected line number
  EXACT_SELECTION="$(clipster -c -o -n 500 -0 \
                   | gawk 'BEGIN {RS = "\0"; ORS = "\0"} NF > 0 { print }' \
                   | gawk 'BEGIN {RS = "\0"}'"NR == $NUMBER { print; exit }")"

  # Echo the selection back to clipster
  echo -n "$EXACT_SELECTION" | clipster -c
fi


code:
#!/bin/sh

timestamp="$(date +%Y%m%d%H%M%S)"
targetbase="$HOME/screenshots"
mkdir -p $targetbase
[ -d $targetbase ] || exit 1

case $1 in
  full)
    type="$targetbase/full_screnshot_$timestamp.png"
    /usr/bin/maim $type
    notify-send "Archivo guardado en $type"
    ;;
  selected_window)
    type="$targetbase/selected_window_$timestamp.png"
    /usr/bin/maim -st 9999999 | convert - \( +clone -background black -shadow 80x3+5+5 \) +swap -background none -layers merge +repage $type
    notify-send "Archivo guardado en $type"
    ;;
  selected_area)
    type="$targetbase/selected_area_$timestamp.png"
    /usr/bin/maim -s $type | xclip -selection clipboard -t image/png
    notify-send "Archivo guardado en $type"
    ;;
esac

exit 0


code:
#!/bin/bash

timestamp="$(date +%Y%m%d%H%M%S)"
targetbase="$HOME/screencast"
mkdir -p $targetbase

# Obtener las coordenadas y el tamaño de la ventana seleccionada
# Esto excluye la decoración de la ventana.
unset x y w h
eval $(xwininfo | sed -n -e "s/^ \+Absolute upper-left X: \+\([0-9]\+\).*/x=\1/p" \
                      -e "s/^ \+Absolute upper-left Y: \+\([0-9]\+\).*/y=\1/p" \
                     -e "s/^ \+Width: \+\([0-9]\+\).*/w=\1/p" \
                     -e "s/^ \+Height: \+\([0-9]\+\).*/h=\1/p" )
$w=$w + $w % 2 # que el ancho sea múltiplo de 2, sino ffmpeg se queja
WIN_XY=$x","$y # dar formato a las coordenadas XY
WIN_GEO=$w"x"$h # dar formato al tamaño de la ventana
echo $WIN_XY
echo $WIN_GEO
# notify-send mostrará un mensaje indicando el inicio del screencast.
# correr ffmpeg con los parámetros que se ajusten a tu configuración.
[ -d $targetbase ] || exit 1
notify-send "Iniciando screencast..." && ffmpeg -f alsa -ac 1 -i pulse -f x11grab -r 25 -s $WIN_GEO -i :0.0+$WIN_XY -acodec libmp3lame -async 1 -vcodec libx264 -preset ultrafast -crf 0 -threads 0 $targetbase/screencast_$timestamp.mkv


code:
#!/bin/bash
notify-send "Finalizando screencast..." && killall ffmpeg


code:
#!/bin/bash

torify /usr/bin/git "$@"


code:
#!/bin/sh

# ------------------------------------------------------------------------------
#
# Modified TMUX start script from:
#	 http://forums.gentoo.org/viewtopic-t-836006-start-0.html
#
# Store it to `~/bin/tmx` and issue `chmod +x`.
#
# ------------------------------------------------------------------------------

function check_session() {
	local postfix="$1"
	shift

	"${tmux[@]}" -L "session-$postfix" list-sessions -F "#S" 2>/dev/null | grep -q "$base_session-$postfix"
}

tmux=( "tmux" )
base_session="$USER"

if [[ "$XDG_SESSION_ID" ]] && check_session "$XDG_SESSION_ID"; then
	tmux+=( "-L" "session-$XDG_SESSION_ID" )
	base_session+="-$XDG_SESSION_ID"
fi

# ------------------------------------------------------------------------------

new_session="${base_session}-$$"

if (( $("${tmux[@]}" ls | wc -l) == 0 )); then
	exec "${tmux[@]}" new -s "$new_session"
else
	# Count tmux sessions (1 master + N slaves).
	# If there are no slave sessions, do not create new windows.
	if (( $("${tmux[@]}" ls | wc -l) > 1 )); then
		NEW_WINDOW_COMMAND=("new-window" "$*" ";")
	fi

	# Create a new session (without attaching it) and link to base session to share windows
	# Attach to the new session & kill it once orphaned
	exec "${tmux[@]}" new-session -d -t "$base_session" -s "$new_session" \; \
	                  attach-session -t "$new_session" \; \
	                  "${NEW_WINDOW_COMMAND[@]}" \
	                  set-option destroy-unattached
fi


code:
#!/usr/bin/env sh

DISPLAY1="$(bspc query -M --names | awk -F: '{print $1}' | grep 'eDP1\|VGA-0')"
[[ ! -z "$DISPLAY1" ]] && bspc monitor "$DISPLAY1" -d 1 2 3 4 5 6 7 8 9 10 11 12 && bspc config -m "$DISPLAY1" top_padding 18

[[ -z `pgrep enforce` ]] && ~/.bin/enforce "$DISPLAY1" '^1' &

bspc config border_width 1
bspc config window_gap 3

bspc config split_ratio 0.5
bspc config borderless_monocle false
bspc config single_monocle true
bspc config gapless_monocle false
bspc config focus_follows_pointer true
bspc config focused_border_color "#585858"
bspc config normal_border_color "#12181d"
bspc config active_border_color "#585858"
bspc config presel_feedback_color "#9e9e9e"
bspc config click_to_focus any
bspc config honor_size_hints false
bspc config ignore_ewmh_focus true

bspc config external_rules_command "$XDG_CONFIG_HOME/bspwm/rules"

# Workspaces
bspc rule -a 'Firefox:Navigator' follow=on desktop=^1
bspc rule -a 'Firefox Developer Edition:Navigator' follow=on desktop=^1
bspc rule -a Qutebrowser follow=on desktop=^1
bspc rule -a Iceweasel follow=on desktop=^1
bspc rule -a TelegramDesktop follow=on desktop=^2 state=tiled
bspc rule -a URxvt:chat follow=on desktop=^2 state=tiled
bspc rule -a URxvt:URxvtQuake sticky=on state=floating
bspc rule -a Thunderbird follow=on desktop=^3
bspc rule -a Icedove follow=on desktop=^3
bspc rule -a Doublecmd follow=on desktop=^4
bspc rule -a URxvt:ranger follow=on desktop=^4 state=tiled
bspc rule -a JDownloader follow=off  desktop=^5
bspc rule -a Lxappearance follow=on desktop=^6 state=floating
bspc rule -a Anydesk follow=on desktop=^6 state=tiled
bspc rule -a Remmina follow=on desktop=^6 state=tiled
bspc rule -a qt5ct follow=on desktop=^6 state=floating
bspc rule -a mpv follow=on desktop=^7 state=tiled
bspc rule -a obs follow=on desktop=^7 state=tiled
bspc rule -a cantata follow=on desktop=^7 state=tiled
bspc rule -a Easytag follow=on desktop=^7 state=tiled
bspc rule -a *:libreoffice follow=off desktop=^8
bspc rule -a Soffice follow=off desktop=^8
bspc rule -a Zathura follow=on desktop=^8 state=tiled
bspc rule -a Emacs follow=on desktop=^9
bspc rule -a Wine follow=off desktop=^12 state=tiled

# Floating apps
bspc rule -a sxiv follow=off state=floating
bspc rule -a URxvt:terminal follow=off state=floating
bspc rule -a 'Firefox:firefox' follow=off state=floating manage=off
bspc rule -a 'Firefox:Browser' follow=off state=floating manage=off
bspc rule -a 'Firefox Developer Edition:firefox-developer-edition' follow=off state=floating manage=off
bspc rule -a 'Firefox Developer Edition:Browser' follow=off state=floating manage=off

# Xresources
xrdb ~/.Xresources &
# Wallpaper
[[ -e $HOME/.fehbg ]] && $HOME/.fehbg &
# i3lock Fancy
[[ -z `pgrep xss-lock` ]] && xss-lock -- i3lock-fancy -p &
# clipboard
[[ -z `pgrep clipboard` ]] && ~/.bin/clipboard &
# panel
[[ -z `pgrep panel` ]] && ~/.bin/panel &
# udiskie
[[ -z `pgrep udiskie` ]] && udiskie &
# sxhkd
[[ -z `pgrep sxhkd` ]] && sxhkd &


code:
#!/usr/bin/env zsh
# https://github.com/jenniges/dotfiles/blob/master/bspwm/bspwmrc

wid="$1"
class="$2"
instance="$3"

out=()

case $class in
	Soffice | libreoffice)
		case $(xprop -id $wid _NET_WM_WINDOW_TYPE) in
			*_NET_WM_WINDOW_TYPE_NORMAL* ) out+='state=tiled' ;;
		esac
		;;
	Java )
		case $(xprop -id $wid _NET_WM_WINDOW_TYPE) in
			*_NET_WM_WINDOW_TYPE_SPLASH* ) out+='state=floating' ;;
		esac
		;;
	Firefox )
		(( $(bspc query -N -d | wc -l) >= 1 )) && out+='focus=off'
		;;
esac

(( ${#out} )) && print $out


code:
#!/usr/bin/env sh
#
# bspwm hotkeys
#

# Apps

# Program Launcher
super + space
  ~/.bin/rofi_run

# Clipboard
alt + c
  ~/.bin/roficlip

# Password Manager
super + period
  rofi-pass

# Screen Manager
super + F8
  ~/.bin/rofi-xrandr

# Window Switch
alt + Tab
  rofi -show window -width 36

# Exit Menu
super + Escape
  ~/.bin/exit

# Take Screenshot
Print
  teiler

# Restart bspwm
super + shift + r
  ~/.config/bspwm/bspwmrc

# Terminal
super + Return
  urxvtcd -g 100x30 -name terminal

# Cli Apps
super + shift + {f,i}
  urxvtcd {-name ranger -e ranger, -name chat -e weechat}

# Volume
alt + {m,Up,Down}
  pamixer {-t,-i 1,-d 1}

# Reload Funtions
super + shift + Escape
  pkill -USR1 -x sxhkd

# Mouse Focus
~button1
  bspc node pointed -f

#
# bspwm hotkeys
#

# close and kill
super + w
  bspc node -c

# alternate between the tiled and monocle layout
super + m
  bspc desktop -l next

# if the current node is automatic, send it to the last manual, otherwise pull the last leaf
super + y
  bspc query -N -n focused.automatic && bspc node -n last.!automatic || bspc node last.leaf -n focused

# swap the current node and the biggest node
super + g
  bspc node -s bigges

#
# state/flags
#

# set the window state
super + {t,shift + t,s,f}
  bspc node -t {tiled,pseudo_tiled,floating,fullscreen}

# set the node flags
super + ctrl + {x,y,z}
  bspc node -g {locked,sticky,private}

#
# focus/swap
#

# focus the node in the given direction
super + {_,shift + }{h,j,k,l}
  bspc node -{f,s} {west,south,north,east}

# focus the node for the given path jump
super + {p,b,comma,period}
  bspc node -f @{parent,brother,first,second}

# focus the next/previous node in the current desktop
super + {_,shift + }c
  bspc node -f {next,prev}.local

# focus the next/previous desktop in the current monitor
super + bracket{left,right}
  bspc desktop -f {prev,next}.local

# focus the last node/desktop
super + {grave,Tab}
  bspc {node,desktop} -f last

# focus the older or newer node in the focus history
super + {o,i}
  bspc wm -h off; \
  bspc node {older,newer} -f; \
  bspc wm -h on

# focus or send to the given desktop
super + {_,shift + }{0-9}
  bspc {desktop -f,node -d} '^{0-9}'

#
# preselect
#

# preselect the direction
super + ctrl + {h,j,k,l}
  bspc node -p {west,south,north,east}

# preselect the ratio
super + ctrl + {1-9}
  bspc node -o 0.{1-9}

# cancel the preselection for the focused node
super + ctrl + space
  bspc node -p cancel

# cancel the preselection for the focused desktop
super + ctrl + shift + space
  bspc query -N -d | xargs -I id -n 1 bspc node id -p cancel

#
# move/resize
#

# expand a window by moving one of its side outward
super + alt + {h,j,k,l}
  bspc node -z {left -20 0,bottom 0 20,top 0 -20,right 20 0}

# contract a window by moving one of its side inward
super + alt + shift + {h,j,k,l}
  bspc node -z {right -20 0,top 0 20,bottom 0 -20,left 20 0}

# move a floating window
super + {Left,Down,Up,Right}
  bspc node -v {-20 0,0 20,0 -20,20 0}


code:
[clipster]
default_selection = CLIPBOARD
duplicates = no
history_size = 50
history_update_interval = 60
smart_update = 1


code:
#################################
#
# Backend
#
#################################

backend = "glx";
glx-no-stencil = true;
glx-copy-from-front = false;
glx-swap-method = "undefined";

#################################
#
# Shadows
#
#################################

shadow = true;
no-dnd-shadow = true;
no-dock-shadow = true;
clear-shadow = true;
shadow-radius = 12;
shadow-offset-x = -15;
shadow-offset-y = -15;
shadow-opacity = 0.75;
shadow-red = 0.0;
shadow-green = 0.0;
shadow-blue = 0.0;
shadow-exclude = [
    "! name~=''",
    "name = 'Notification'",
    "name = 'Plank'",
    "name = 'Docky'",
    "name = 'Kupfer'",
    "name = 'xfce4-notifyd'",
    "name *= 'VLC'",
    "name *= 'compton'",
    "name *= 'Chromium'",
    "name *= 'Chrome'",
    "name *= 'Faeria.x86_64'",
    "class_g = 'Conky'",
    "class_g = 'Kupfer'",
    "class_g = 'Synapse'",
    "class_g ?= 'Notify-osd'",
    "class_g ?= 'Cairo-dock'",
    "class_g ?= 'Xfce4-notifyd'",
    "class_g ?= 'Xfce4-power-manager'"
];
shadow-ignore-shaped = false;

#################################
#
# Opacity
#
#################################

menu-opacity = 1;
active-opacity = 1;
frame-opacity = 1;
alpha-step = 0.06;
blur-background = false;
blur-background-frame = false;
blur-background-fixed = false;
blur-background-exclude = [
    "window_type = 'dock'",
    "window_type = 'desktop'",
    "name *= 'Faeria.x86_64'"
];

#################################
#
# Fading
#
#################################

fading = true;
fade-delta = 1;
fade-in-step = 0.01;
fade-out-step = 0.01;
no-fading-openclose = false;
fade-exclude = [
    "name *= 'Faeria.x86_64'"
];

#################################
#
# Other
#
#################################

mark-wmwin-focused = true;
mark-ovredir-focused = true;
use-ewmh-active-win = true;
detect-rounded-corners = true;
detect-client-opacity = true;
refresh-rate = 0;
vsync = "opengl-swc";
dbe = false;
paint-on-overlay = true;
sw-opti = false;
unredir-if-possible = true;
focus-exclude = [ ];
detect-transient = true;
detect-client-leader = true;

#################################
#
# Window type settings
#
#################################

wintypes:
{
    tooltip =
    {
        fade = true;
        shadow = true;
        opacity = 0.85;
        focus = true;
    };
};


code:
[global]
    font = Misc Tamsyn 10

    # allow a small subset of html markup:
    # bold
    # italic
    # <s>strikethrough<s/>
    # underline
    #
    # for a complete reference see http://developer.gnome.org/pango/stable/PangoMarkupFormat.html
    # If markup is not allowed, those tags will be stripped out of the message.
    allow_markup = yes

    # The format of the message. Possible variables are:
    #   %a  appname
    #   %s  summary
    #   %b  body
    #   %i  iconname (including its path)
    #   %I  iconname (without its path)
    #   %p  progress value if set ([  0%] to [100%]) or nothing
    # Markup is allowed
    format = "%a: %s\n%b"

    # Sort messages by urgency
    sort = yes

    # Show how many messages are currently hidden (because of geometry)
    indicate_hidden = yes

    # alignment of message text.
    # Possible values are "left", "center" and "right"
    alignment = left

    # The frequency with wich text that is longer than the notification
    # window allows bounces back and forth.
    # This option conflicts with 'word_wrap'.
    # Set to 0 to disable
    bounce_freq = 0

    # show age of message if message is older than show_age_threshold seconds.
    # set to -1 to disable
    show_age_threshold = 60

    # split notifications into multiple lines if they don't fit into geometry
    word_wrap = yes

    # ignore newlines '\n' in notifications
    ignore_newline = no

    # the geometry of the window
    # geometry [{width}]x{height}][+/-{x}+/-{y}]
    # The geometry of the message window.
    # The height is measured in number of notifications everything else in pixels. If the width
    # is omitted but the height is given ("-geometry x2"), the message window
    # expands over the whole screen (dmenu-like). If width is 0,
    # the window expands to the longest message displayed.
    # A positive x is measured from the left, a negative from the
    # right side of the screen.  Y is measured from the top and down respectevly.
    # The width can be negative. In this case the actual width is the
    # screen width minus the width defined in within the geometry option.
    geometry = "300x5-30+20"

    # The transparency of the window. range: [0; 100]
    # This option will only work if a compositing windowmanager is present (e.g. xcompmgr, compiz, etc..)
    transparency = 0

    # Don't remove messages, if the user is idle (no mouse or keyboard input)
    # for longer than idle_threshold seconds.
    # Set to 0 to disable.
    idle_threshold = 120

    # Which monitor should the notifications be displayed on.
    monitor = 0

    # Display notification on focused monitor. Possible modes are:
    # mouse: follow mouse pointer
    # keyboard: follow window with keyboard focus
    # none: don't follow anything
    #
    # "keyboard" needs a windowmanager that exports the _NET_ACTIVE_WINDOW property.
    # This should be the case for almost all modern windowmanagers.
    #
    # If this option is set to mouse or keyboard, the monitor option will be
    # ignored.
    follow = none

    # should a notification popped up from history be sticky or
    # timeout as if it would normally do.
    sticky_history = yes

    # The height of a single line. If the height is smaller than the font height,
    # it will get raised to the font height.
    # This adds empty space above and under the text.
    line_height = 0

    # Draw a line of 'separatpr_height' pixel height between two notifications.
    # Set to 0 to disable
    separator_height = 2

    # padding between text and separator
    padding = 8

    # horizontal padding
    horizontal_padding = 8

    # Define a color for the separator.
    # possible values are:
    #  * auto: dunst tries to find a color fitting to the background
    #  * foreground: use the same color as the foreground
    #  * frame: use the same color as the frame.
    #  * anything else will be interpreted as a X color
    separator_color = frame

    # print a notification on startup
    # This is mainly for error detection, since dbus (re-)starts dunst
    # automatically after a crash.
    startup_notification = true

    # dmenu path
    dmenu = /usr/bin/dmenu -p dunst:

    # browser for opening urls in context menu
    browser = /usr/bin/firefox -new-tab

[frame]
    width = 1
    color = "#292929"

[urgency_low]
    # IMPORTANT: colors have to be defined in quotation marks.
    # Otherwise the '#' and following  would be interpreted as a comment.
    background = "#121212"
    foreground = "#888888"
    timeout = 10

[urgency_normal]
    background = "#121212"
    foreground = "#ffffff"
    timeout = 10

[urgency_critical]
    background = "#121212"
    foreground = "#CC9393"
    timeout = 0


code:
# EditorConfig is awesome: http://EditorConfig.org

# top-most EditorConfig file
root = true

# Unix-style newlines with a newline ending every file
[*]
indent_style = space
indent_size = 2
max_line_length=80
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

# Matches multiple files with brace expansion notation
# Set default charset
[*.{js,py}]
charset = utf-8

# 4 space indentation
[*.py]
indent_style = space
indent_size = 4

# Tab indentation (no size specified)
[Makefile]
indent_style = tab

# Indentation override for all JS under lib directory
[lib/**.js]
indent_style = space
indent_size = 2

# Matches the exact files either package.json or .travis.yml
[{package.json,.travis.yml},*.jade,*.js,*.xml,*.html,*.el]
indent_style = space
indent_size = 2

# LaTeX Style
[*.{tex,bib,lyx,lua}]
indent_style = space
indent_size = 2